Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
CRC-32

  七誌
経緯
1.       ZIPの実装でCRC-32が必要になった
2.       そもそもCRCって何だろう?
3.       Wikipediaで何やら説明されている
4.       読んだけど意味がよくわからない
     •    ...
結論から言うと
• ZIPで使われているCRC-32はIEEE 802.3




• CRCの計算は特殊な割り算の余り
• マジックナンバーは検算用の値
目次

1.   計算編   ―   Wikipediaの解説を追試
2.   理論編   ―   計算方法の根拠
3.   手順編   ―   CRC-32の計算手順
4.   実装編   ―   実装に必要なテクニックなど
5.   番外編...
1. 計算編
Wikipediaの解説を追試
手探り
• どこから手を付ければ良いんだろう?
• とりあえずWikipediaに書いてある計算をやっ
  てみよう
CRCの計算
1. 先頭が一致ならXOR
2. 右シフト
左端まで1~2を繰り返す


  11010011101100
  1011
CRCの計算
1. 先頭が一致ならXOR
2. 右シフト
左端まで1~2を繰り返す


  11010011101100
  1011
  0110
CRCの計算
1. 先頭が一致ならXOR
2. 右シフト
左端まで1~2を繰り返す


  01100011101100
  1011
CRCの計算
1. 先頭が一致ならXOR
2. 右シフト
左端まで1~2を繰り返す


  01100011101100
   1011
    0111
CRCの計算
1. 先頭が一致ならXOR
2. 右シフト
左端まで1~2を繰り返す


  00111011101100
   1011
CRCの計算
1. 先頭が一致ならXOR
2. 右シフト
左端まで1~2を繰り返す


  00111011101100
    1011
    0101
CRCの計算
1. 先頭が一致ならXOR
2. 右シフト
左端まで1~2を繰り返す


  00010111101100
    1011
CRCの計算
1. 先頭が一致ならXOR
2. 右シフト
左端まで1~2を繰り返す


  00010111101100
     1011
     0000
CRCの計算
1. 先頭が一致ならXOR
2. 右シフト
左端まで1~2を繰り返す


  00000001101100
     1011
CRCの計算
1. 先頭が一致ならXOR
2. 右シフト
左端まで1~2を繰り返す


  00000001101100
         1011
         0110
CRCの計算
1. 先頭が一致ならXOR
2. 右シフト
左端まで1~2を繰り返す


  00000000110100
         1011
CRCの計算
1. 先頭が一致ならXOR
2. 右シフト
左端まで1~2を繰り返す


  00000000110100
          1011
          0110
CRCの計算
1. 先頭が一致ならXOR
2. 右シフト
左端まで1~2を繰り返す


  00000000011000
          1011
CRCの計算
1. 先頭が一致ならXOR
2. 右シフト
左端まで1~2を繰り返す


  00000000011000
           1011
           0111
CRCの計算
1. 先頭が一致ならXOR
2. 右シフト
左端まで1~2を繰り返す


  00000000001110
           1011
CRCの計算
1. 先頭が一致ならXOR
2. 右シフト
左端まで1~2を繰り返す


  00000000001110
            1011
            0101
CRCの計算
1. 先頭が一致ならXOR
2. 右シフト
左端まで1~2を繰り返す
                求める値

  00000000000101
            1011
まとめ


              0x34ec CRC-3
                上位1bitを付加

• 0x34ecに対するCRC-3の値
• Wikipediaの一覧表にCRC-3はない
• 計算例として仮に出しただけ?
2. 理論編
  CRCの計算方法は
どのような根拠に基づくのか
modulo 2
• 計算例で求めた値はmodulo 2の剰余
 – 0x34ec mod2 0xb = 5
• modulo 2とは、繰り上がり・繰り下がりを無視
  して各桁を独立に計算する方法
• 足し算・引き算・XORが同一の値
 – ...
割り算(普通)
• 10進数の割り算は掛け算が必要
• 2進数は0と1しかないため掛け算が不要
        28                11100
    35 987    100011 1111011011
          ...
割り算(modulo 2)
• 引き算の代わりに排他的論理和(XOR)
            11100               11111
100011 1111011011   100011 1111011011
       100...
なぜmodulo 2?
• CRCはデータチェックが目的
 – 割り算をすること自体に意味はない
• データの破損が検出できれば何でも良い
 – 通常の算数と違っても問題はない
• 計算が簡単なmodulo 2を採用
 – 引き算は繰り下がりで...
CRC-32
• 除数0x104c11db7によるmodulo 2剰余
• バイト配列を巨大数に見立てて割る
• 前処理・後処理で検出力向上
 – 前処理(被除数)→計算→後処理(剰余)
 – modulo 2除算自体は素直に計算
• サンプル...
3. 手順編
CRC-32の計算手順
被除数の作成 (1)
• バイトごとにビット順序を反転
 – “a” → 01100001 → 10000110 → 0x86
 – “b” → 01100010 → 01000110 → 0x46
 – “ab” → 0x86 0x46
 –...
被除数の作成 (2)
• 4バイトの0を後置
 – “a” → 0x86 0x00 0x00 0x00 0x00
• ビッグエンディアンとして数値化
 – “a” → 0x8600000000
 – “abcd” → 0x8646c626000...
前処理(被除数)
• そのままでは直前の0が無視される
 – “a” → 0x8600000000
 – “¥0¥0a” → 0x00008600000000
 – 0の個数の誤りが検出不可能
• 対策として上位4バイトのビット値を反転
 – ...
除数(1)
• Wikipediaにある多項式は除数
• x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+
  x4+x2+x+1
• x = 2 → 232+226+223+222+・・・+22+21+20
...
除数(2)
•  Wikipediaで多項式の横にある3つの値は、
   計算用に除数から派生した値
1. 除数から最上位ビットを落とした値
    – 0x104c11db7 → 0x04c11db7
2. 1のビット順序を反転した値
   ...
modulo 2剰余
• 除数0x104c11db7でmodulo 2剰余
 – “a” → 0x79ffffff00 mod2 0x104c11db7
   → 0x3d8212e8
 – “abcd”
   → 0x79b939d90000...
後処理(剰余)
• 剰余のビット順序を反転
 – “a” → 0x3d8212e8 → 0x174841bc
 – “abcd” → 0x774cbe48 → 0x127d32ee
 – 入力をバイトごとに反転した反動?
• ビット値を反転して...
実装例(F#)
• ビット順序を反転する関数を定義
let rev (v:uint32) =
    let mutable ret = 0u
    for i = 0 to 31 do
        if v &&& (1u <<< i)...
実装例(F#)
• データが1バイトの場合
let crc32_1 (b:byte) =
    let b' = uint32 b
    let mutable 被除数 = uint64(~~~(rev b')) <<< 8
    let...
実装例(F#)
• データが4バイトの場合
let crc32_4 (buf:byte[]) =
    let buf' = BitConverter.ToUInt32(buf, 0)
    let mutable 被除数 = uint64...
検算(Python)
• 既存実装としてPythonと比較
>>> from struct import pack
>>> from binascii import crc32, hexlify
>>> hexlify(pack(">i", c...
まとめ
1.       入力
     •     “abcd” → 0x61 0x62 0x63 0x64
2.       バイトごとにビット順序を反転
     •     0x86 0x46 0xc6 0x26
3.       4バ...
4. 実装編
実装に必要なテクニックなど
巨大数
• 巨大なデータをそのまま数値化して被除数と
  して扱うのは困難
 – 手順編の例で、“abcd”のように被除数が64bitに
   収まるようにしたのはそのため
• 除数は33bitだが、32bitで扱えないか?
 – たった1bi...
シフトの相対性
• 計算編では除数をシフト
 – 被除数   ←11010011101100
 – 除数    ←1011→
• 除数を固定して被除数をシフトしても、計算結
  果は変わらない
 – 被除数   ←11010011101100
...
実装例(F#)
let crc32_4 (buf:byte[]) =
                                              除数をシフト
    let buf' = BitConverter.ToUInt...
最上位ビット
• 被除数の最上位ビットはXORで0になる
 – 被除数    ←11010011101100
 – 除数     ←1011
• 被除数の最上位ビットは値だけ見て、シフトで
  押し出して捨ててしまっても構わない
 – どうせ捨...
実装例(F#)
let crc32_4 (buf:byte[]) =
                                             除数が33bit
    let buf' = BitConverter.ToUIn...
ビット順序の反転(1)
• 計算を反転させるとどうなるか?
• 標準
 – 被除数   ←11010011101100
 – 除数    ←1011
• 反転
 – 被除数   ←00110111001011→
 – 除数    ←      ...
ビット順序の反転(2)
• 元はコードのあちこちで反転させていた
• 計算自体を反転させると、反転が相殺して消
  え、コードが単純化になる
 – データをバイトごとに反転させる必要がなくなる
• 除数は反転した値を用意して使う
 – Wiki...
実装例(F#)
let crc32_4 (buf:byte[]) =
                                                 標準
    let buf' = BitConverter.ToUInt3...
データ逐次投入(1)
被除数を一気に作成(標準)                        被除数を一気に作成(反転)
1.       データ                         1.   データ
     –    “abc...
データ逐次投入(2)
被除数を一気に作成(反転)                       被除数を逐次投入で作成
1.   データ                            1. 初期値(4バイト反転込み)
     –   “...
データ逐次投入(3)
• CRC計算との関係
 – 初期値     ffffffff→
 – データ           61→
               62→
             63→
           64→
      ...
データ逐次投入(4)
• データを逐次投入しながら計   初期値 ffffffff→
                  データ
  算を進めても、同一の結果が             61→
                  除数  edb...
実装例(F#)
let crc32_4 (buf:byte[]) =
                                             一気に用意
    let buf' = BitConverter.ToUInt32...
テーブル
• ビット単位で計算すると無駄が多い
• テーブルを用いてバイト単位で計算
 – 1バイト(0~255)のすべての計算パターンを事
   前にキャッシュしておく
• XORの交換法則により、あらかじめ計算した
  値を後で重ねても、同...
実装例(F#)
let crc32_table =
    [| for i in 0..255 ->
        let mutable reg = uint32 i
        for j = 0 to 7 do
         ...
5. 番外編
CRCの特性によるマジックナンバー
マジックナンバー(1)
1. データのCRCを計算
2. データの後に1で計算したCRCを追加
3. 2のCRCを計算
 – データの内容に関係なく常に同じ値になる
 – この性質を検算に利用することがある

    データ    CRC   ...
マジックナンバー(2)
• CRC-32で確認、見事に一致!
 – “a” → 0xe8b7be43 → 0x2144df1c
 – “abcd” → 0xed82cd11 → 0x2144df1c
 – XORによる相殺の結果
• CRCは最...
検算(Python)
>>> from struct import pack
>>> from binascii import crc32
>>> def magic(data1):
...     crc1 = crc32(data1)
.....
ご清聴ありがとうございました
Upcoming SlideShare
Loading in …5
×

CRC-32

22,461 views

Published on

CRC-32の説明です。

Published in: Technology
  • Manifestation Magic� - $27 - By Alexander Wilson - 96% Off ▲▲▲ http://scamcb.com/manifmagic/pdf
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes ,Download or read Ebooks here ... ......................................................................................................................... Download FULL PDF EBOOK here { https://urlzs.com/UABbn }
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT (Unlimited) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m77EgH } ......................................................................................................................... Download Full EPUB Ebook here { http://bit.ly/2m77EgH } ......................................................................................................................... ACCESS WEBSITE for All Ebooks ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m77EgH } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m77EgH } ......................................................................................................................... Download doc Ebook here { http://bit.ly/2m77EgH } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT (Unlimited) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { https://tinyurl.com/y6a5rkg5 } ......................................................................................................................... Download Full EPUB Ebook here { https://tinyurl.com/y6a5rkg5 } ......................................................................................................................... ACCESS WEBSITE for All Ebooks ......................................................................................................................... Download Full PDF EBOOK here { https://tinyurl.com/y6a5rkg5 } ......................................................................................................................... Download EPUB Ebook here { https://tinyurl.com/y6a5rkg5 } ......................................................................................................................... Download doc Ebook here { https://tinyurl.com/y6a5rkg5 } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • DOWNLOAD THIS BOOKS INTO AVAILABLE FORMAT (Unlimited) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { https://tinyurl.com/y6a5rkg5 } ......................................................................................................................... Download Full EPUB Ebook here { https://tinyurl.com/y6a5rkg5 } ......................................................................................................................... ACCESS WEBSITE for All Ebooks ......................................................................................................................... Download Full PDF EBOOK here { https://tinyurl.com/y6a5rkg5 } ......................................................................................................................... Download EPUB Ebook here { https://tinyurl.com/y6a5rkg5 } ......................................................................................................................... Download doc Ebook here { https://tinyurl.com/y6a5rkg5 } ......................................................................................................................... ......................................................................................................................... ......................................................................................................................... .............. Browse by Genre Available eBooks ......................................................................................................................... Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, Cookbooks, Crime, Ebooks, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult,
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

CRC-32

  1. 1. CRC-32 七誌
  2. 2. 経緯 1. ZIPの実装でCRC-32が必要になった 2. そもそもCRCって何だろう? 3. Wikipediaで何やら説明されている 4. 読んだけど意味がよくわからない • CRC-32の規格が色々あるけどどれ? • 0x04c11db7とかの定数は何? • ZIP仕様書の0xdebb20e3との関係は? 5. というわけで調べてみた
  3. 3. 結論から言うと • ZIPで使われているCRC-32はIEEE 802.3 • CRCの計算は特殊な割り算の余り • マジックナンバーは検算用の値
  4. 4. 目次 1. 計算編 ― Wikipediaの解説を追試 2. 理論編 ― 計算方法の根拠 3. 手順編 ― CRC-32の計算手順 4. 実装編 ― 実装に必要なテクニックなど 5. 番外編 ― マジックナンバー
  5. 5. 1. 計算編 Wikipediaの解説を追試
  6. 6. 手探り • どこから手を付ければ良いんだろう? • とりあえずWikipediaに書いてある計算をやっ てみよう
  7. 7. CRCの計算 1. 先頭が一致ならXOR 2. 右シフト 左端まで1~2を繰り返す 11010011101100 1011
  8. 8. CRCの計算 1. 先頭が一致ならXOR 2. 右シフト 左端まで1~2を繰り返す 11010011101100 1011 0110
  9. 9. CRCの計算 1. 先頭が一致ならXOR 2. 右シフト 左端まで1~2を繰り返す 01100011101100 1011
  10. 10. CRCの計算 1. 先頭が一致ならXOR 2. 右シフト 左端まで1~2を繰り返す 01100011101100 1011 0111
  11. 11. CRCの計算 1. 先頭が一致ならXOR 2. 右シフト 左端まで1~2を繰り返す 00111011101100 1011
  12. 12. CRCの計算 1. 先頭が一致ならXOR 2. 右シフト 左端まで1~2を繰り返す 00111011101100 1011 0101
  13. 13. CRCの計算 1. 先頭が一致ならXOR 2. 右シフト 左端まで1~2を繰り返す 00010111101100 1011
  14. 14. CRCの計算 1. 先頭が一致ならXOR 2. 右シフト 左端まで1~2を繰り返す 00010111101100 1011 0000
  15. 15. CRCの計算 1. 先頭が一致ならXOR 2. 右シフト 左端まで1~2を繰り返す 00000001101100 1011
  16. 16. CRCの計算 1. 先頭が一致ならXOR 2. 右シフト 左端まで1~2を繰り返す 00000001101100 1011 0110
  17. 17. CRCの計算 1. 先頭が一致ならXOR 2. 右シフト 左端まで1~2を繰り返す 00000000110100 1011
  18. 18. CRCの計算 1. 先頭が一致ならXOR 2. 右シフト 左端まで1~2を繰り返す 00000000110100 1011 0110
  19. 19. CRCの計算 1. 先頭が一致ならXOR 2. 右シフト 左端まで1~2を繰り返す 00000000011000 1011
  20. 20. CRCの計算 1. 先頭が一致ならXOR 2. 右シフト 左端まで1~2を繰り返す 00000000011000 1011 0111
  21. 21. CRCの計算 1. 先頭が一致ならXOR 2. 右シフト 左端まで1~2を繰り返す 00000000001110 1011
  22. 22. CRCの計算 1. 先頭が一致ならXOR 2. 右シフト 左端まで1~2を繰り返す 00000000001110 1011 0101
  23. 23. CRCの計算 1. 先頭が一致ならXOR 2. 右シフト 左端まで1~2を繰り返す 求める値 00000000000101 1011
  24. 24. まとめ 0x34ec CRC-3 上位1bitを付加 • 0x34ecに対するCRC-3の値 • Wikipediaの一覧表にCRC-3はない • 計算例として仮に出しただけ?
  25. 25. 2. 理論編 CRCの計算方法は どのような根拠に基づくのか
  26. 26. modulo 2 • 計算例で求めた値はmodulo 2の剰余 – 0x34ec mod2 0xb = 5 • modulo 2とは、繰り上がり・繰り下がりを無視 して各桁を独立に計算する方法 • 足し算・引き算・XORが同一の値 – 0+0=0-0=0^0=0 0+1=0-1=0^1=1 – 1+0=1-0=1^0=1 1+1=1-1=1^1=0 – 実装では加算・減算の代用にXORを使う • つまりCRCとは特殊な割り算の余り
  27. 27. 割り算(普通) • 10進数の割り算は掛け算が必要 • 2進数は0と1しかないため掛け算が不要 28 11100 35 987 100011 1111011011 除数まま→ 100011 掛け算→ 70 引き算→ 110101 引き算→ 287 除数まま→ 100011 掛け算→ 280 引き算→ 100100 除数まま→ 100011 引き算→ 7 引き算→ 111
  28. 28. 割り算(modulo 2) • 引き算の代わりに排他的論理和(XOR) 11100 11111 100011 1111011011 100011 1111011011 100011 100011 引き算→ 110101 XOR→ 111101 100011 100011 引き算→ 100100 XOR→ 111100 100011 100011 引き算→ 111 XOR→ 111111 100011 XOR→ 111001 100011 XOR→ 11010
  29. 29. なぜmodulo 2? • CRCはデータチェックが目的 – 割り算をすること自体に意味はない • データの破損が検出できれば何でも良い – 通常の算数と違っても問題はない • 計算が簡単なmodulo 2を採用 – 引き算は繰り下がりで他の桁に影響 – XORは他の桁に影響を及ぼさない
  30. 30. CRC-32 • 除数0x104c11db7によるmodulo 2剰余 • バイト配列を巨大数に見立てて割る • 前処理・後処理で検出力向上 – 前処理(被除数)→計算→後処理(剰余) – modulo 2除算自体は素直に計算 • サンプル実装は最適化されている – 原理と実装のつながりが分かりにくい – 最適化を考慮して仕様が決められた?
  31. 31. 3. 手順編 CRC-32の計算手順
  32. 32. 被除数の作成 (1) • バイトごとにビット順序を反転 – “a” → 01100001 → 10000110 → 0x86 – “b” → 01100010 → 01000110 → 0x46 – “ab” → 0x86 0x46 – “abcd” → 0x86 0x46 0xc6 0x26 • 計算のハードウェア処理を考慮? – シリアルポートのプロトコルとも関係? – Wikipediaにそのようなことが書いてある
  33. 33. 被除数の作成 (2) • 4バイトの0を後置 – “a” → 0x86 0x00 0x00 0x00 0x00 • ビッグエンディアンとして数値化 – “a” → 0x8600000000 – “abcd” → 0x8646c62600000000 • 被除数を除数より大きくするための処置 – 被除数<除数 のとき 被除数=剰余 – 被除数がそのまま剰余になるのを回避
  34. 34. 前処理(被除数) • そのままでは直前の0が無視される – “a” → 0x8600000000 – “¥0¥0a” → 0x00008600000000 – 0の個数の誤りが検出不可能 • 対策として上位4バイトのビット値を反転 – “a” → 0x8600000000 → 0x79ffffff00 – “¥0¥0a” → 0x00008600000000 → 0xffff79ff000000 • ff×4に続く00の個数は検知不能 – レアケースのため無視?
  35. 35. 除数(1) • Wikipediaにある多項式は除数 • x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+ x4+x2+x+1 • x = 2 → 232+226+223+222+・・・+22+21+20 – 2進数でビットが立つ位置を表す式 • 100000100110000010001110110110111 • 0x104c11db7 (=CRC-32の除数) • CRCの種類ごとに除数は異なる
  36. 36. 除数(2) • Wikipediaで多項式の横にある3つの値は、 計算用に除数から派生した値 1. 除数から最上位ビットを落とした値 – 0x104c11db7 → 0x04c11db7 2. 1のビット順序を反転した値 – 0x04c11db7 → 0xedb88320 3. 除数を1ビット右シフトした値 – 0x104c11db7 >> 1 → 0x82608edb • 1と2は実装編で説明、3は用途不明
  37. 37. modulo 2剰余 • 除数0x104c11db7でmodulo 2剰余 – “a” → 0x79ffffff00 mod2 0x104c11db7 → 0x3d8212e8 – “abcd” → 0x79b939d900000000 mod2 0x104c11db7 → 0x774cbe48 • 計算方法のカスタマイズはない – 実装上の都合により計算方法は変形して実装さ れるが(後述)、計算結果は同一
  38. 38. 後処理(剰余) • 剰余のビット順序を反転 – “a” → 0x3d8212e8 → 0x174841bc – “abcd” → 0x774cbe48 → 0x127d32ee – 入力をバイトごとに反転した反動? • ビット値を反転してCRC-32の値とする – “a” → 0x174841bc → 0xe8b7be43 – “abcd” → 0x127d32ee → 0xed82cd11 – 前処理で上位4バイトを反転した反動? • 反転によりマジックナンバー出現(後述)
  39. 39. 実装例(F#) • ビット順序を反転する関数を定義 let rev (v:uint32) = let mutable ret = 0u for i = 0 to 31 do if v &&& (1u <<< i) <> 0u then ret <- ret ||| (1u <<< (31 - i)) ret printfn "%x" (rev 1u) // 80000000 • 破壊的代入に突っ込まないでください・・・
  40. 40. 実装例(F#) • データが1バイトの場合 let crc32_1 (b:byte) = let b' = uint32 b let mutable 被除数 = uint64(~~~(rev b')) <<< 8 let 除数 = 0x104c11db7UL let 最上位 = 0x100000000UL for i = 7 downto 0 do if 被除数 &&& (最上位 <<< i) <> 0UL then 被除数 <- 被除数 ^^^ (除数 <<< i) rev(~~~(uint32 被除数)) printf "%x" (crc32_1(byte 'a')) // e8b7be43
  41. 41. 実装例(F#) • データが4バイトの場合 let crc32_4 (buf:byte[]) = let buf' = BitConverter.ToUInt32(buf, 0) let mutable 被除数 = uint64(~~~(rev buf')) <<< 32 let 除数 = 0x104c11db7UL let 最上位 = 0x100000000UL for i = 31 downto 0 do if 被除数 &&& (最上位 <<< i) <> 0UL then 被除数 <- 被除数 ^^^ (除数 <<< i) rev(~~~(uint32 被除数)) let bytes = Encoding.ASCII.GetBytes "abcd" printf "%x" (crc32_4 bytes) // ed82cd11
  42. 42. 検算(Python) • 既存実装としてPythonと比較 >>> from struct import pack >>> from binascii import crc32, hexlify >>> hexlify(pack(">i", crc32("a"))) 'e8b7be43' >>> hexlify(pack(">i", crc32("abcd"))) 'ed82cd11' • F#の独自実装で求めた値と一致! – “a” → 0xe8b7be43 – “abcd” → 0xed82cd11
  43. 43. まとめ 1. 入力 • “abcd” → 0x61 0x62 0x63 0x64 2. バイトごとにビット順序を反転 • 0x86 0x46 0xc6 0x26 3. 4バイトの0を後置してビッグエンディアンとして数値化 • 0x8646c62600000000 4. 上位4バイトのビット値を反転 (ここまで前処理) • 0x79b939d900000000 5. 除数0x104c11db7でmodulo 2の剰余を計算 • 0x774cbe48 6. 剰余のビット順序を反転 (ここから後処理) • 0x127d32ee 7. ビット値を反転してCRC-32の値とする • 0xed82cd11
  44. 44. 4. 実装編 実装に必要なテクニックなど
  45. 45. 巨大数 • 巨大なデータをそのまま数値化して被除数と して扱うのは困難 – 手順編の例で、“abcd”のように被除数が64bitに 収まるようにしたのはそのため • 除数は33bitだが、32bitで扱えないか? – たった1bitはみ出しただけなのに・・・ • 実装に際して何らかの工夫が必要 – 既存の実装は色々あるのに、工夫の意味を理解 しないとまともに読めない!
  46. 46. シフトの相対性 • 計算編では除数をシフト – 被除数 ←11010011101100 – 除数 ←1011→ • 除数を固定して被除数をシフトしても、計算結 果は変わらない – 被除数 ←11010011101100 – 除数 ←1011 • 計算に関係するのはあくまで相対位置
  47. 47. 実装例(F#) let crc32_4 (buf:byte[]) = 除数をシフト let buf' = BitConverter.ToUInt32(buf, 0) let mutable 被除数 = uint64(~~~(rev buf')) <<< 32 let 除数 = 0x104c11db7UL let 最上位 = 0x100000000UL for i = 31 downto 0 do if 被除数 &&& (最上位 <<< i) <> 0UL then 被除数 <- 被除数 ^^^ (除数 <<< i) rev(~~~(uint32 被除数)) let crc32_4 (buf:byte[]) = 被除数をシフト let buf' = BitConverter.ToUInt32(buf, 0) let mutable 被除数 = uint64(~~~(rev buf')) let 除数 = 0x104c11db7UL let 最上位 = 0x100000000UL for i = 0 to 31 do 被除数 <- (if 被除数 &&& 最上位 = 0UL then 被除数 else (被除数 ^^^ 除数)) <<< 1 rev(~~~(uint32 被除数))
  48. 48. 最上位ビット • 被除数の最上位ビットはXORで0になる – 被除数 ←11010011101100 – 除数 ←1011 • 被除数の最上位ビットは値だけ見て、シフトで 押し出して捨ててしまっても構わない – どうせ捨てるので、除数とXORする必要はない – XORしないなら、除数から最上位ビットを取り除 いても計算結果に影響しない • CRC-32の除数が1bit減って32bitに収まる
  49. 49. 実装例(F#) let crc32_4 (buf:byte[]) = 除数が33bit let buf' = BitConverter.ToUInt32(buf, 0) let mutable 被除数 = uint64(~~~(rev buf')) let 除数 = 0x104c11db7UL let 最上位 = 0x100000000UL for i = 0 to 31 do 被除数 <- (if 被除数 &&& 最上位 = 0UL then 被除数 else (被除数 ^^^ 除数)) <<< 1 rev(~~~(uint32 被除数)) let crc32_4 (buf:byte[]) = 計算を32bit化 let buf' = BitConverter.ToUInt32(buf, 0) let mutable 被除数 = ~~~(rev buf') let 除数 = 0x04c11db7u // Wikipediaに出てきた値(標準) let 最上位 = 0x80000000u for i = 0 to 31 do let 被除数' = 被除数 <<< 1 被除数 <- if 被除数 &&& 最上位 = 0u then 被除数' else 被除数' ^^^ 除数 rev(~~~被除数)
  50. 50. ビット順序の反転(1) • 計算を反転させるとどうなるか? • 標準 – 被除数 ←11010011101100 – 除数 ←1011 • 反転 – 被除数 ←00110111001011→ – 除数 ← 1101 • 最終的に得られた結果を反転すれば、同じ値 が得られる
  51. 51. ビット順序の反転(2) • 元はコードのあちこちで反転させていた • 計算自体を反転させると、反転が相殺して消 え、コードが単純化になる – データをバイトごとに反転させる必要がなくなる • 除数は反転した値を用意して使う – Wikipediaに出てきた0xedb88320 • これを想定して規格が決められた? – いずれにしても計算は単純な方が良い
  52. 52. 実装例(F#) let crc32_4 (buf:byte[]) = 標準 let buf' = BitConverter.ToUInt32(buf, 0) let mutable 被除数 = ~~~(rev buf') let 除数 = 0x04c11db7u // Wikipediaに出てきた値(標準) let 最上位 = 0x80000000u for i = 0 to 31 do let 被除数' = 被除数 <<< 1 被除数 <- if 被除数 &&& 最上位 = 0u then 被除数' else 被除数' ^^^ 除数 rev(~~~被除数) let crc32_4 (buf:byte[]) = 反転 let buf' = BitConverter.ToUInt32(buf, 0) let mutable 被除数 = ~~~buf' let 除数 = 0xedb88320u // Wikipediaに出てきた値(反転) for i = 0 to 31 do let 被除数' = 被除数 >>> 1 被除数 <- if 被除数 &&& 1u = 0u then 被除数' else 被除数' ^^^ 除数 ~~~被除数
  53. 53. データ逐次投入(1) 被除数を一気に作成(標準) 被除数を一気に作成(反転) 1. データ 1. データ – “abcde” – “abcde” 2. 16進数 2. 16進数 – 0x61 0x62 0x63 0x64 0x65 – 0x61 0x62 0x63 0x64 0x65 3. ビット順序反転 3. バイト順序反転 – 0x86 0x46 0xc6 0x26 0xa6 – 0x65 0x64 0x63 0x62 0x61 4. 数値化 4. 数値化 – 0x8646c626a600000000 – 0x6564636261 5. 4バイトビット値反転 5. 4バイトビット値反転 – 0x79b939d9a600000000 – 0x659b9c9d9e
  54. 54. データ逐次投入(2) 被除数を一気に作成(反転) 被除数を逐次投入で作成 1. データ 1. 初期値(4バイト反転込み) – “abcde” – ffffffff 2. 16進数 2. 下位から1文字ずつXOR – 0x61 0x62 0x63 0x64 0x65 – ffffffff 3. バイト順序反転 ^ 61 – 0x65 0x64 0x63 0x62 0x61 ^ 62 4. 数値化 ^ 63 ^ 64 – 0x6564636261 ^ 65 5. 4バイトビット値反転 3. 結果 – 0x659b9c9d9e – 0x659b9c9d9e
  55. 55. データ逐次投入(3) • CRC計算との関係 – 初期値 ffffffff→ – データ 61→ 62→ 63→ 64→ 66→ – 除数 edb88320 • これらをXORで重ねて計算を進める
  56. 56. データ逐次投入(4) • データを逐次投入しながら計 初期値 ffffffff→ データ 算を進めても、同一の結果が 61→ 除数 edb88320 得られる ffffff→ • 交換法則による計算順序の 62→ 入れ替え edb88320 ffff→ • XORは交換法則が成り立つ 63→ • 逐次投入により、任意の長さ edb88320 のデータ処理が可能 ff→ 64→ edb88320 65→ edb88320
  57. 57. 実装例(F#) let crc32_4 (buf:byte[]) = 一気に用意 let buf' = BitConverter.ToUInt32(buf, 0) let mutable 被除数 = ~~~buf' let 除数 = 0xedb88320u for i = 0 to 31 do let 被除数' = 被除数 >>> 1 被除数 <- if 被除数 &&& 1u = 0u then 被除数' else 被除数' ^^^ 除数 ~~~被除数 let crc32 (buf:byte[]) = 逐次投入により任意長対応 let mutable 被除数 = ~~~0u let 除数 = 0xedb88320u for b in buf do 被除数 <- 被除数 ^^^ uint32(b) for j = 0 to 7 do let 被除数' = 被除数 >>> 1 被除数 <- if 被除数 &&& 1u = 0u then 被除数' else 被除数' ^^^ 除数 ~~~被除数
  58. 58. テーブル • ビット単位で計算すると無駄が多い • テーブルを用いてバイト単位で計算 – 1バイト(0~255)のすべての計算パターンを事 前にキャッシュしておく • XORの交換法則により、あらかじめ計算した 値を後で重ねても、同一の結果となる • CRCのサンプル実装として出回っているコー ドの大半はテーブルを用いている
  59. 59. 実装例(F#) let crc32_table = [| for i in 0..255 -> let mutable reg = uint32 i for j = 0 to 7 do let reg' = reg >>> 1 reg <- if reg &&& 1u = 0u then reg' else reg' ^^^ 0xedb88320u reg |] let crc32 (buf:byte[]) = let mutable reg = ~~~0u for b in buf do reg <- reg ^^^ (uint32 b) let t = crc32_table.[int(reg) &&& 0xff] reg <- (reg >>> 8) ^^^ t ~~~reg • 大抵のサンプル実装は似たようなコード
  60. 60. 5. 番外編 CRCの特性によるマジックナンバー
  61. 61. マジックナンバー(1) 1. データのCRCを計算 2. データの後に1で計算したCRCを追加 3. 2のCRCを計算 – データの内容に関係なく常に同じ値になる – この性質を検算に利用することがある データ CRC CRC 常に同じ値=マジックナンバー
  62. 62. マジックナンバー(2) • CRC-32で確認、見事に一致! – “a” → 0xe8b7be43 → 0x2144df1c – “abcd” → 0xed82cd11 → 0x2144df1c – XORによる相殺の結果 • CRCは最後にビット値を反転するが、反転す る前の0xdebb20e3がZIP仕様書に記載され ているマジックナンバー – ~0xdebb20e3 → 0x2144df1c • 後処理で反転する目的がこれ?
  63. 63. 検算(Python) >>> from struct import pack >>> from binascii import crc32 >>> def magic(data1): ... crc1 = crc32(data1) ... data2 = data1 + pack("<i", crc1) ... return crc32(data2) ... >>> hex(magic("a")) '0x2144df1c' >>> hex(magic("abcd")) '0x2144df1c' >>> hex(magic("abcdefghijklmn")) '0x2144df1c'
  64. 64. ご清聴ありがとうございました

×