Cryptol_02_資料型別

VikingsQ發表於2021-01-03

Cryptol 資料型別

下載學習的參考資料:https://cryptol.net/documentation.html

資料型別

  1. 基礎資料型別:bits, sequences, integers, integers-modulo-n, rationals, tuples, and records;此外,可以對資料型別進行巢狀;

  2. 型別定義:

    12:[8] //12是8bit資料型別;

    12:[_] //12是bit資料型別,但位寬自動推導;

  3. bits :

    可以在Cryptol命令列中輸入以下內容,看結果

    True
    false
    False : Bit
    if True && False then 0x3 else 0x4
    False || True
    (True && False) ^ True
    ~False
    ~(False || True)
    

    語言是大小寫敏感的

  4. 字:

    1. word實際上是一定位寬的bits,通常是非負的,位寬無限大,且預設是16進製表示;

    2. set base = 10可以將預設進位制修改為10進位制,其餘類推;

    3. 也可以在定義時顯示的指明進位制:

      0b11111011110 // binary
      0o3736 // octal
      2014 // decimal
      0x7de // hexadecimal

    4. 最好不使用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.

  5. 整數:

    1. 整數是無界的,即無限位寬;注意和bit型別的區別
    2. 將bit型別轉換成integer型別:toInteger 0xff
    3. 定義負整數-12:- to Integer 0xc
  6. 有理數:

    有理數的定義方法有以下幾種,以下建立方式都表示為1/2:

    ratio 1 2 //用ratio函式顯示地建立
    ratio 2 4
    (1 /. 2) : Rational 
    (recip 2) : Rational //recip表示倒數
    (fromInteger (-1) /. fromInteger (-2)) : Rational .//利用fromInteger和整數建立
    
  7. 浮點數://暫時用不上;

  8. 元組:異構集合

    1. 元組是具有任意型別的任意值的簡單有序集合。元組用括號括住兩個或多個逗號分隔的元素。Cryptol還支援一種特殊的零元素元組,編寫為( )元組型別,其語法類似於元組值。它們是用圓括號括住兩個或兩個以上的常見型別。元組型別的值是相同長度的元組,其中每個位置的值都有相應的型別。例如,型別([8],Bits)包括第一個元素是8 bits字,第二個元素是一個bit。空元組()是()型別的唯一值。

    2. 輸入輸出測試:

      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)))
      
    3. 可以利用點運算子訪問元組中的元素,和陣列下標類似;

      (1, 2+4).0
      (1, 2+4).1
      ((1, 2), False, (3-1, (4, True))).2.1
      
  9. 序列:同構集合,類似於陣列;

    1. 序列的元素集合可以包括序列本身;
    [1, 2]
    [[1, 2, 3], [4, 5, 6], [7, 8, 9]] //代表3x3矩陣
    
  10. 序列的列舉型別:用於方便地描述序列;

    [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)
    
  11. 序列的Comprehensions 理解型別,這個型別比較奇怪:

    1. 當只有一個|,是窮舉;
    2. 兩個或者更多|,就類似於並行的概念,不太好說清楚;
  12. 序列的追加和索引;

    1. 索引既可以從前向後,也可以從後向前;
    2. 索引既可以選擇一個,也可以索引多個;
    [] # [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
    
  13. 有限和無限長的序列:

    1. 注意不要由於定義無限長序列,而使得程式陷入死迴圈;
    2. 1:[32] 表示32bit位寬的1,…用於定義無限長的序列,@用於前向訪問序列中的元素,注意不能用!來後向訪問序列中的元素;
    [1:[32] ...]
    [1:[32], 3 ...]
    [1:[32] ...] @ 2000
    [1:[32], 3 ...] @@ [300, 500, 700]
    [100, 102 ...]
    
  14. 操作序列:

    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]]
    
  15. 移位和旋轉:

    [1, 2, 3, 4, 5] >> 2 //邏輯右移
    [1, 2, 3, 4, 5] << 2 //邏輯左移
    [1, 2, 3, 4, 5] >>> 2 //迴圈右移
    [1, 2, 3, 4, 5] <<< 2 //迴圈左移
    
  16. 字和序列的一致性;

    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
    
  17. 字元和字串本質上是序列;

    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"
    
  18. 紀錄型別:有名稱的元組,類似於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
    
  19. 零;

    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}
    
  20. 算數運算:

    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
    
    1. 整數除法向下截斷;

      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)
      
  21. 型別的總結

    1. 最好明確地指明資料的位寬、長度等,可以用**:t**命令看系統為你推匯出什麼型別;

    2. 單態資料型別:型別明確的資料型別,就如之前所介紹的;

    3. 多型資料型別:

      1. 用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, ...]
        
      2. tail的資料型別,下面這個例子說明tail的資料型別是可修改的:類似於函式過載的概念,即定義多個相同的函式名,引數列表不盡相同,使用時自動選擇;但又和過載的概念不同,類似於多型的概念;(即繼承基函式時,會根據呼叫函式的不同物件,呼叫不同的成源函式)

        tail : [5][8] -> [4][8] //[5][8]表示長度為5,每個元素的寬度是8的序列;->的左側是接收的資料型別,右側是產生的資料型別,整體形成函式;
        
      3. 可以利用:t命令,檢視tail的輸入輸出型別:

        Cryptol> :t tail
        tail : {n, a} [1 + n]a -> [n]a //輸入長度為n+1的a型別,輸出長度為n;
        
      4. 還包括split、take等命令;

相關文章