下载学习的参考资料:https://cryptol.net/documentation.html
基础数据类型:bits, sequences, integers, integers-modulo-n, rationals, tuples, and records;此外,可以对数据类型进行嵌套;
类型定义:
12:[8] //12是8bit数据类型;
12:[_] //12是bit数据类型,但位宽自动推导;
bits :
可以在Cryptol命令行中输入以下内容,看结果
True
false
False : Bit
if True && False then 0x3 else 0x4
False || True
(True && False) ^ True
~False
~(False || True)
语言是大小写敏感的
字:
word实际上是一定位宽的bits,通常是非负的,位宽无限大,且默认是16进制表示;
set base = 10
可以将默认进制修改为10进制,其余类推;
也可以在定义时显示的指明进制:
0b11111011110 // binary
0o3736 // octal
2014 // decimal
0x7de // hexadecimal
最好不使用10进制数,因为10进制数的位宽不确定;
Decimal numbers may assume any of a variety of types in Cryptol; that is, they are polymorphic. For example, 19 could have the unbounded type Integer (see section 1.4), type [8], type [5], or any other word type with at least 5 bits.
整数:
toInteger 0xff
- to Integer 0xc
有理数:
有理数的定义方法有以下几种,以下创建方式都表示为1/2:
ratio 1 2 //用ratio函数显示地创建
ratio 2 4
(1 /. 2) : Rational
(recip 2) : Rational //recip表示倒数
(fromInteger (-1) /. fromInteger (-2)) : Rational .//利用fromInteger和整数创建
浮点数://暂时用不上;
元组:异构集合
元组是具有任意类型的任意值的简单有序集合。元组用括号括住两个或多个逗号分隔的元素。Cryptol还支持一种特殊的零元素元组,编写为( )元组类型,其语法类似于元组值。它们是用圆括号括住两个或两个以上的常见类型。元组类型的值是相同长度的元组,其中每个位置的值都有相应的类型。例如,类型([8],Bits)包括第一个元素是8 bits字,第二个元素是一个bit。空元组()是()类型的唯一值。
输入输出测试:
Cryptol> (1, 2+4)
(0x1, 0x6)
Cryptol> (True, False, True ^ False)
(True, False, True)
Cryptol> ((1, 2), False, (3-1, (4, True)))
((0x1, 0x2), False, (0x2, (0x4, True)))
可以利用点运算符访问元组中的元素,和数组下标类似;
(1, 2+4).0
(1, 2+4).1
((1, 2), False, (3-1, (4, True))).2.1
序列:同构集合,类似于数组;
[1, 2]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]] //代表3x3矩阵
序列的列举类型:用于方便地描述序列;
[1 .. 10] // increment with step 1
[1, 3 .. 10] // increment with step 2 (= 3-1)
[10, 9 .. 1] // decrement with step 1 (= 10-9)
[10, 9 .. 20] // decrement with step 1 (= 10-9)
[10, 7 .. 1] // decrement with step 3 (= 10-7)
[10, 11 .. 1] // increment with step 1
[1 .. 10 : [8]] // increment 8-bit words with step 1
[1, 3 .. 10 : [16]] // increment 16-bit words with step 2 (= 3-1)
序列的Comprehensions 理解类型,这个类型比较奇怪:
序列的追加和索引;
[] # [1, 2]
[1, 2] # []
[1 .. 5] # [3, 6, 8]
[0 .. 9] @ 0
[0 .. 9] @ 5
[0 .. 9] @ 10
[0 .. 9] @@ [3, 4]
[0 .. 9] @@ []
[0 .. 9] @@ [9, 12]
[0 .. 9] @@ [9, 8 .. 0]
[0 .. 9] ! 0
[0 .. 9] ! 3
[0 .. 9] !! [3, 6]
[0 .. 9] !! [0 .. 9]
[0 .. 9] ! 12
有限和无限长的序列:
[1:[32] ...]
[1:[32], 3 ...]
[1:[32] ...] @ 2000
[1:[32], 3 ...] @@ [300, 500, 700]
[100, 102 ...]
操作序列:
take`{3} [1 .. 12] //取前三个
drop`{3} [1 .. 12] //去掉前三个
split`{3} [1 .. 12] //平均分成三组
groupBy`{3} [1 .. 12] //每组三个进行分组
join [[1 .. 4], [5 .. 8], [9 .. 12]] //合并
join [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]] //合并
transpose [[1, 2, 3, 4], [5, 6, 7, 8]] //将每个组的第一个作为一组,第二个作为一组...
transpose [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
移位和旋转:
[1, 2, 3, 4, 5] >> 2 //逻辑右移
[1, 2, 3, 4, 5] << 2 //逻辑左移
[1, 2, 3, 4, 5] >>> 2 //循环右移
[1, 2, 3, 4, 5] <<< 2 //循环左移
字和序列的一致性;
Cryptol> 12:[4]
0xc
Cryptol> 12 # [False]
0x18
Cryptol> [False, False] # 12
0x0c
Cryptol> [True, False] # 12
0x2c
Cryptol> 12 # [False, True]
0x31
Cryptol> 32:[6]
0x20
Cryptol> 12 # 32 //1100 100000
0x320
Cryptol> [True, False, True, False, True, False] == 42
True
字符和字符串本质上是序列;
Cryptol> :set base=10
Cryptol> :set ascii=off
Cryptol> 'A'
65
Cryptol> "ABC"
[65, 66, 67]
Cryptol> :set ascii=on
Cryptol> "ABC"
"ABC"
Cryptol> :set ascii=off
Cryptol> ['A' .. 'Z']
[65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90]
Cryptol> :set ascii=on
Cryptol> ['A' .. 'Z']
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
纪录类型:有名称的元组,类似于C++的vector,键值对;
Cryptol> {xCoord = 12:[32], yCoord = 21:[32]}
{xCoord = 0x0000000c, yCoord = 0x00000015}
Cryptol> {xCoord = 12:[32], yCoord = 21:[32]}.yCoord
0x00000015
Cryptol> {name = "Cryptol", address = "Galois"}
{name = [0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x6c],
address = [0x47, 0x61, 0x6c, 0x6f, 0x69, 0x73]}
Cryptol> {name = "Cryptol", address = "Galois"}.address
[0x47, 0x61, 0x6c, 0x6f, 0x69, 0x73]
Cryptol> {name = "test", coords = {xCoord = 3:[32], yCoord = 5:[32]}}
{name = [0x74, 0x65, 0x73, 0x74],
coords = {xCoord = 0x00000003, yCoord = 0x00000005}}
Cryptol> {name = "test", coords = {xCoord = 3:[32], \
yCoord = 5:[32]}}.coords.yCoord
0x00000005
Cryptol> {x=True, y=False} == {y=False, x=True}
True
零;
Cryptol> zero : Bit
False
Cryptol> zero : [8]
0
Cryptol> zero : Integer
0
Cryptol> zero : Z 19
0
Cryptol> zero : Rational
(ratio 0 1)
Cryptol> zero : ([8], Bit)
(0, False)
Cryptol> zero : [8][3]
[0, 0, 0, 0, 0, 0, 0, 0]
Cryptol> zero : [3](Bit, [4])
[(False, 0), (False, 0), (False, 0)]
Cryptol> zero : {xCoord : [12], yCoord : [5]}
{xCoord=0, yCoord=0}
算数运算:
Cryptol> 2 / 0
division by 0
Cryptol> 2 % 0
division by 0
Cryptol> 3 + (if 3 == 2+1 then 12 else 2/0)
15
Cryptol> 3 + (if 3 != 2+1 then 12 else 2/0)
division by 0
Cryptol> lg2 (-25) : [_]
0x03
整数除法向下截断;
Cryptol> (6 / 3, 6 % 3)
(2, 0)
Cryptol> (7 / 3, 7 % 3)
(2, 1)
Cryptol> (8 / 3, 8 % 3)
(2, 2)
Cryptol> (9 / 3, 9 % 3)
(3, 0)
类型的总结
最好明确地指明数据的位宽、长度等,可以用**:t**命令看系统为你推导出什么类型;
单态数据类型:类型明确的数据类型,就如之前所介绍的;
多态数据类型:
用tail函数删除第一个元素:
Cryptol> tail [1 .. 5]
[2, 3, 4, 5]
Cryptol> tail [(False, (1:[8])), (True, 12), (False, 3)]
[(True, 12), (False, 3)]
Cryptol> tail [ (1:[16])... ]
[2, 3, 4, 5, 6, ...]
tail的数据类型,下面这个例子说明tail的数据类型是可修改的:类似于函数重载的概念,即定义多个相同的函数名,参数列表不尽相同,使用时自动选择;但又和重载的概念不同,类似于多态的概念;(即继承基函数时,会根据调用函数的不同对象,调用不同的成源函数)
tail : [5][8] -> [4][8] //[5][8]表示长度为5,每个元素的宽度是8的序列;->的左侧是接收的数据类型,右侧是产生的数据类型,整体形成函数;
可以利用:t命令,查看tail的输入输出类型:
Cryptol> :t tail
tail : {n, a} [1 + n]a -> [n]a //输入长度为n+1的a类型,输出长度为n;
还包括split、take等命令;