SlideShare une entreprise Scribd logo
1  sur  64
CRC-32

  七誌
経緯
1.       ZIPの実装でCRC-32が必要になった
2.       そもそもCRCって何だろう?
3.       Wikipediaで何やら説明されている
4.       読んだけど意味がよくわからない
     •    CRC-32の規格が色々あるけどどれ?
     •    0x04c11db7とかの定数は何?
     •    ZIP仕様書の0xdebb20e3との関係は?
5. というわけで調べてみた
結論から言うと
• 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が同一の値
 – 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とは特殊な割り算の余り
割り算(普通)
• 10進数の割り算は掛け算が必要
• 2進数は0と1しかないため掛け算が不要
        28                11100
    35 987    100011 1111011011
             除数まま→   100011
 掛け算→  70
              引き算→    110101
 引き算→  287   除数まま→    100011
 掛け算→  280    引き算→     100100
             除数まま→     100011
 引き算→    7
              引き算→          111
割り算(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
なぜmodulo 2?
• CRCはデータチェックが目的
 – 割り算をすること自体に意味はない
• データの破損が検出できれば何でも良い
 – 通常の算数と違っても問題はない
• 計算が簡単なmodulo 2を採用
 – 引き算は繰り下がりで他の桁に影響
 – XORは他の桁に影響を及ぼさない
CRC-32
• 除数0x104c11db7によるmodulo 2剰余
• バイト配列を巨大数に見立てて割る
• 前処理・後処理で検出力向上
 – 前処理(被除数)→計算→後処理(剰余)
 – modulo 2除算自体は素直に計算
• サンプル実装は最適化されている
 – 原理と実装のつながりが分かりにくい
 – 最適化を考慮して仕様が決められた?
3. 手順編
CRC-32の計算手順
被除数の作成 (1)
• バイトごとにビット順序を反転
 – “a” → 01100001 → 10000110 → 0x86
 – “b” → 01100010 → 01000110 → 0x46
 – “ab” → 0x86 0x46
 – “abcd” → 0x86 0x46 0xc6 0x26
• 計算のハードウェア処理を考慮?
 – シリアルポートのプロトコルとも関係?
 – Wikipediaにそのようなことが書いてある
被除数の作成 (2)
• 4バイトの0を後置
 – “a” → 0x86 0x00 0x00 0x00 0x00
• ビッグエンディアンとして数値化
 – “a” → 0x8600000000
 – “abcd” → 0x8646c62600000000
• 被除数を除数より大きくするための処置
 – 被除数<除数 のとき 被除数=剰余
 – 被除数がそのまま剰余になるのを回避
前処理(被除数)
• そのままでは直前の0が無視される
 – “a” → 0x8600000000
 – “¥0¥0a” → 0x00008600000000
 – 0の個数の誤りが検出不可能
• 対策として上位4バイトのビット値を反転
 – “a” → 0x8600000000 → 0x79ffffff00
 – “¥0¥0a” → 0x00008600000000
   → 0xffff79ff000000
• ff×4に続く00の個数は検知不能
 – レアケースのため無視?
除数(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の種類ごとに除数は異なる
除数(2)
•  Wikipediaで多項式の横にある3つの値は、
   計算用に除数から派生した値
1. 除数から最上位ビットを落とした値
    – 0x104c11db7 → 0x04c11db7
2. 1のビット順序を反転した値
    – 0x04c11db7 → 0xedb88320
3. 除数を1ビット右シフトした値
    – 0x104c11db7 >> 1 → 0x82608edb
•   1と2は実装編で説明、3は用途不明
modulo 2剰余
• 除数0x104c11db7でmodulo 2剰余
 – “a” → 0x79ffffff00 mod2 0x104c11db7
   → 0x3d8212e8
 – “abcd”
   → 0x79b939d900000000 mod2 0x104c11db7
   → 0x774cbe48
• 計算方法のカスタマイズはない
 – 実装上の都合により計算方法は変形して実装さ
   れるが(後述)、計算結果は同一
後処理(剰余)
• 剰余のビット順序を反転
 – “a” → 0x3d8212e8 → 0x174841bc
 – “abcd” → 0x774cbe48 → 0x127d32ee
 – 入力をバイトごとに反転した反動?
• ビット値を反転してCRC-32の値とする
 – “a” → 0x174841bc → 0xe8b7be43
 – “abcd” → 0x127d32ee → 0xed82cd11
 – 前処理で上位4バイトを反転した反動?
• 反転によりマジックナンバー出現(後述)
実装例(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


• 破壊的代入に突っ込まないでください・・・
実装例(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
実装例(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
検算(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
まとめ
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
4. 実装編
実装に必要なテクニックなど
巨大数
• 巨大なデータをそのまま数値化して被除数と
  して扱うのは困難
 – 手順編の例で、“abcd”のように被除数が64bitに
   収まるようにしたのはそのため
• 除数は33bitだが、32bitで扱えないか?
 – たった1bitはみ出しただけなのに・・・
• 実装に際して何らかの工夫が必要
 – 既存の実装は色々あるのに、工夫の意味を理解
   しないとまともに読めない!
シフトの相対性
• 計算編では除数をシフト
 – 被除数   ←11010011101100
 – 除数    ←1011→
• 除数を固定して被除数をシフトしても、計算結
  果は変わらない
 – 被除数   ←11010011101100
 – 除数    ←1011
• 計算に関係するのはあくまで相対位置
実装例(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 被除数))
最上位ビット
• 被除数の最上位ビットはXORで0になる
 – 被除数    ←11010011101100
 – 除数     ←1011
• 被除数の最上位ビットは値だけ見て、シフトで
  押し出して捨ててしまっても構わない
 – どうせ捨てるので、除数とXORする必要はない
 – XORしないなら、除数から最上位ビットを取り除
   いても計算結果に影響しない
• CRC-32の除数が1bit減って32bitに収まる
実装例(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(~~~被除数)
ビット順序の反転(1)
• 計算を反転させるとどうなるか?
• 標準
 – 被除数   ←11010011101100
 – 除数    ←1011
• 反転
 – 被除数   ←00110111001011→
 – 除数    ←          1101
• 最終的に得られた結果を反転すれば、同じ値
  が得られる
ビット順序の反転(2)
• 元はコードのあちこちで反転させていた
• 計算自体を反転させると、反転が相殺して消
  え、コードが単純化になる
 – データをバイトごとに反転させる必要がなくなる
• 除数は反転した値を用意して使う
 – Wikipediaに出てきた0xedb88320
• これを想定して規格が決められた?
 – いずれにしても計算は単純な方が良い
実装例(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 被除数' ^^^ 除数
    ~~~被除数
データ逐次投入(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
データ逐次投入(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
データ逐次投入(3)
• CRC計算との関係
 – 初期値     ffffffff→
 – データ           61→
               62→
             63→
           64→
         66→
 – 除数      edb88320
• これらをXORで重ねて計算を進める
データ逐次投入(4)
• データを逐次投入しながら計   初期値 ffffffff→
                  データ
  算を進めても、同一の結果が             61→
                  除数  edb88320
  得られる                  ffffff→
• 交換法則による計算順序の              62→
  入れ替え                edb88320
                          ffff→
• XORは交換法則が成り立つ
                            63→
• 逐次投入により、任意の長さ       edb88320
  のデータ処理が可能                 ff→
                            64→
                      edb88320
                            65→
                      edb88320
実装例(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 被除数' ^^^ 除数
    ~~~被除数
テーブル
• ビット単位で計算すると無駄が多い
• テーブルを用いてバイト単位で計算
 – 1バイト(0~255)のすべての計算パターンを事
   前にキャッシュしておく
• XORの交換法則により、あらかじめ計算した
  値を後で重ねても、同一の結果となる
• CRCのサンプル実装として出回っているコー
  ドの大半はテーブルを用いている
実装例(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

• 大抵のサンプル実装は似たようなコード
5. 番外編
CRCの特性によるマジックナンバー
マジックナンバー(1)
1. データのCRCを計算
2. データの後に1で計算したCRCを追加
3. 2のCRCを計算
 – データの内容に関係なく常に同じ値になる
 – この性質を検算に利用することがある

    データ    CRC   CRC

          常に同じ値=マジックナンバー
マジックナンバー(2)
• CRC-32で確認、見事に一致!
 – “a” → 0xe8b7be43 → 0x2144df1c
 – “abcd” → 0xed82cd11 → 0x2144df1c
 – XORによる相殺の結果
• CRCは最後にビット値を反転するが、反転す
  る前の0xdebb20e3がZIP仕様書に記載され
  ているマジックナンバー
 – ~0xdebb20e3 → 0x2144df1c
• 後処理で反転する目的がこれ?
検算(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'
ご清聴ありがとうございました

Contenu connexe

Tendances

プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~Takuya Akiba
 
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門Fixstars Corporation
 
ウェーブレット木の世界
ウェーブレット木の世界ウェーブレット木の世界
ウェーブレット木の世界Preferred Networks
 
いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例Fixstars Corporation
 
SIMDで整数除算
SIMDで整数除算SIMDで整数除算
SIMDで整数除算shobomaru
 
SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介MITSUNARI Shigeo
 
計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミング計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミングNorishige Fukushima
 
きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回Tomoya Kawanishi
 
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarrayRyosuke839
 
いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門Fixstars Corporation
 
競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性Hibiki Yamashiro
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説murachue
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14Ryo Suzuki
 
Rustに触れて私のPythonはどう変わったか
Rustに触れて私のPythonはどう変わったかRustに触れて私のPythonはどう変わったか
Rustに触れて私のPythonはどう変わったかShunsukeNakamura17
 
プログラミングコンテストでのデータ構造 2 ~動的木編~
プログラミングコンテストでのデータ構造 2 ~動的木編~プログラミングコンテストでのデータ構造 2 ~動的木編~
プログラミングコンテストでのデータ構造 2 ~動的木編~Takuya Akiba
 
勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとは勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとはTakuya Akiba
 
高速フーリエ変換
高速フーリエ変換高速フーリエ変換
高速フーリエ変換AtCoder Inc.
 
Re永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドMasaki Hara
 
30分で分かる!OSの作り方
30分で分かる!OSの作り方30分で分かる!OSの作り方
30分で分かる!OSの作り方uchan_nos
 

Tendances (20)

プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
 
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門
 
ウェーブレット木の世界
ウェーブレット木の世界ウェーブレット木の世界
ウェーブレット木の世界
 
いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例
 
SIMDで整数除算
SIMDで整数除算SIMDで整数除算
SIMDで整数除算
 
SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介
 
計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミング計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミング
 
きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回
 
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray
 
いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門
 
競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説
 
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
 
Rustに触れて私のPythonはどう変わったか
Rustに触れて私のPythonはどう変わったかRustに触れて私のPythonはどう変わったか
Rustに触れて私のPythonはどう変わったか
 
プログラミングコンテストでのデータ構造 2 ~動的木編~
プログラミングコンテストでのデータ構造 2 ~動的木編~プログラミングコンテストでのデータ構造 2 ~動的木編~
プログラミングコンテストでのデータ構造 2 ~動的木編~
 
勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとは勉強か?趣味か?人生か?―プログラミングコンテストとは
勉強か?趣味か?人生か?―プログラミングコンテストとは
 
高速フーリエ変換
高速フーリエ変換高速フーリエ変換
高速フーリエ変換
 
Re永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライド
 
30分で分かる!OSの作り方
30分で分かる!OSの作り方30分で分かる!OSの作り方
30分で分かる!OSの作り方
 
Glibc malloc internal
Glibc malloc internalGlibc malloc internal
Glibc malloc internal
 

Similaire à CRC-32

足し算をつくろう
足し算をつくろう足し算をつくろう
足し算をつくろうYoichi Toyota
 
ネイティブコードを語る
ネイティブコードを語るネイティブコードを語る
ネイティブコードを語るKenji Imasaki
 
Javaセキュアコーディングセミナー東京第2回講義
Javaセキュアコーディングセミナー東京第2回講義Javaセキュアコーディングセミナー東京第2回講義
Javaセキュアコーディングセミナー東京第2回講義JPCERT Coordination Center
 
Or seminar2011final
Or seminar2011finalOr seminar2011final
Or seminar2011finalMikio Kubo
 
Intel TSX HLE を触ってみた x86opti
Intel TSX HLE を触ってみた x86optiIntel TSX HLE を触ってみた x86opti
Intel TSX HLE を触ってみた x86optiTakashi Hoshino
 
Schönhage Strassen Algorithm
Schönhage Strassen AlgorithmSchönhage Strassen Algorithm
Schönhage Strassen Algorithmcookies 146
 
Operations research yonezawa_no2
Operations research yonezawa_no2Operations research yonezawa_no2
Operations research yonezawa_no2ssuser0bebd2
 
【Unity道場】ゲーム制作に使う数学を学習しよう
【Unity道場】ゲーム制作に使う数学を学習しよう【Unity道場】ゲーム制作に使う数学を学習しよう
【Unity道場】ゲーム制作に使う数学を学習しようUnity Technologies Japan K.K.
 
Rによる分類木 入門
Rによる分類木 入門Rによる分類木 入門
Rによる分類木 入門Hiro47
 
ロボット技術研究会回路講習会2017-3
ロボット技術研究会回路講習会2017-3ロボット技術研究会回路講習会2017-3
ロボット技術研究会回路講習会2017-3MasayaMorinaga
 
コンピュータシステムの理論と実装2
コンピュータシステムの理論と実装2コンピュータシステムの理論と実装2
コンピュータシステムの理論と実装2H T
 
kagamicomput201710
kagamicomput201710kagamicomput201710
kagamicomput201710swkagami
 
Bluetooth通信の 仕組みと活用法紹介
Bluetooth通信の仕組みと活用法紹介Bluetooth通信の仕組みと活用法紹介
Bluetooth通信の 仕組みと活用法紹介Takehiko YOSHIDA
 
KLab勉強会#6 発表資料
KLab勉強会#6 発表資料KLab勉強会#6 発表資料
KLab勉強会#6 発表資料Suguru Oho
 
kagami_comput2016_02
kagami_comput2016_02kagami_comput2016_02
kagami_comput2016_02swkagami
 
自然言語処理のための機械学習入門1章
自然言語処理のための機械学習入門1章自然言語処理のための機械学習入門1章
自然言語処理のための機械学習入門1章Hiroki Mizukami
 
kagami_comput2016_07
kagami_comput2016_07kagami_comput2016_07
kagami_comput2016_07swkagami
 

Similaire à CRC-32 (20)

足し算をつくろう
足し算をつくろう足し算をつくろう
足し算をつくろう
 
ネイティブコードを語る
ネイティブコードを語るネイティブコードを語る
ネイティブコードを語る
 
Javaセキュアコーディングセミナー東京第2回講義
Javaセキュアコーディングセミナー東京第2回講義Javaセキュアコーディングセミナー東京第2回講義
Javaセキュアコーディングセミナー東京第2回講義
 
実用Brainf*ckプログラミング
実用Brainf*ckプログラミング実用Brainf*ckプログラミング
実用Brainf*ckプログラミング
 
Or seminar2011final
Or seminar2011finalOr seminar2011final
Or seminar2011final
 
計算機理論入門03
計算機理論入門03計算機理論入門03
計算機理論入門03
 
Introduction to programming
Introduction to programmingIntroduction to programming
Introduction to programming
 
Intel TSX HLE を触ってみた x86opti
Intel TSX HLE を触ってみた x86optiIntel TSX HLE を触ってみた x86opti
Intel TSX HLE を触ってみた x86opti
 
Schönhage Strassen Algorithm
Schönhage Strassen AlgorithmSchönhage Strassen Algorithm
Schönhage Strassen Algorithm
 
Operations research yonezawa_no2
Operations research yonezawa_no2Operations research yonezawa_no2
Operations research yonezawa_no2
 
【Unity道場】ゲーム制作に使う数学を学習しよう
【Unity道場】ゲーム制作に使う数学を学習しよう【Unity道場】ゲーム制作に使う数学を学習しよう
【Unity道場】ゲーム制作に使う数学を学習しよう
 
Rによる分類木 入門
Rによる分類木 入門Rによる分類木 入門
Rによる分類木 入門
 
ロボット技術研究会回路講習会2017-3
ロボット技術研究会回路講習会2017-3ロボット技術研究会回路講習会2017-3
ロボット技術研究会回路講習会2017-3
 
コンピュータシステムの理論と実装2
コンピュータシステムの理論と実装2コンピュータシステムの理論と実装2
コンピュータシステムの理論と実装2
 
kagamicomput201710
kagamicomput201710kagamicomput201710
kagamicomput201710
 
Bluetooth通信の 仕組みと活用法紹介
Bluetooth通信の仕組みと活用法紹介Bluetooth通信の仕組みと活用法紹介
Bluetooth通信の 仕組みと活用法紹介
 
KLab勉強会#6 発表資料
KLab勉強会#6 発表資料KLab勉強会#6 発表資料
KLab勉強会#6 発表資料
 
kagami_comput2016_02
kagami_comput2016_02kagami_comput2016_02
kagami_comput2016_02
 
自然言語処理のための機械学習入門1章
自然言語処理のための機械学習入門1章自然言語処理のための機械学習入門1章
自然言語処理のための機械学習入門1章
 
kagami_comput2016_07
kagami_comput2016_07kagami_comput2016_07
kagami_comput2016_07
 

Plus de 7shi

ELFの動的リンク
ELFの動的リンクELFの動的リンク
ELFの動的リンク7shi
 
F#とトランスレータ
F#とトランスレータF#とトランスレータ
F#とトランスレータ7shi
 
F#談話室(3) LT
F#談話室(3) LTF#談話室(3) LT
F#談話室(3) LT7shi
 
マーク&スイープ勉強会
マーク&スイープ勉強会マーク&スイープ勉強会
マーク&スイープ勉強会7shi
 
Cコンパイラの改造(未)
Cコンパイラの改造(未)Cコンパイラの改造(未)
Cコンパイラの改造(未)7shi
 
V6でJIT・部分適用・継続
V6でJIT・部分適用・継続V6でJIT・部分適用・継続
V6でJIT・部分適用・継続7shi
 
ZIP勉強会
ZIP勉強会ZIP勉強会
ZIP勉強会7shi
 
V6 Interpreter (Nagoya Geek Bar 2011-05-02)
V6 Interpreter (Nagoya Geek Bar 2011-05-02)V6 Interpreter (Nagoya Geek Bar 2011-05-02)
V6 Interpreter (Nagoya Geek Bar 2011-05-02)7shi
 
無料環境でWindows Mobileアプリ開発
無料環境でWindows Mobileアプリ開発無料環境でWindows Mobileアプリ開発
無料環境でWindows Mobileアプリ開発7shi
 
LLPML
LLPMLLLPML
LLPML7shi
 

Plus de 7shi (10)

ELFの動的リンク
ELFの動的リンクELFの動的リンク
ELFの動的リンク
 
F#とトランスレータ
F#とトランスレータF#とトランスレータ
F#とトランスレータ
 
F#談話室(3) LT
F#談話室(3) LTF#談話室(3) LT
F#談話室(3) LT
 
マーク&スイープ勉強会
マーク&スイープ勉強会マーク&スイープ勉強会
マーク&スイープ勉強会
 
Cコンパイラの改造(未)
Cコンパイラの改造(未)Cコンパイラの改造(未)
Cコンパイラの改造(未)
 
V6でJIT・部分適用・継続
V6でJIT・部分適用・継続V6でJIT・部分適用・継続
V6でJIT・部分適用・継続
 
ZIP勉強会
ZIP勉強会ZIP勉強会
ZIP勉強会
 
V6 Interpreter (Nagoya Geek Bar 2011-05-02)
V6 Interpreter (Nagoya Geek Bar 2011-05-02)V6 Interpreter (Nagoya Geek Bar 2011-05-02)
V6 Interpreter (Nagoya Geek Bar 2011-05-02)
 
無料環境でWindows Mobileアプリ開発
無料環境でWindows Mobileアプリ開発無料環境でWindows Mobileアプリ開発
無料環境でWindows Mobileアプリ開発
 
LLPML
LLPMLLLPML
LLPML
 

CRC-32