Last active
January 19, 2024 11:13
-
-
Save kujirahand/691a6b57700e1919854810feb8ce1675 to your computer and use it in GitHub Desktop.
CRC32を計算するプログラム - キャッシュテーブルを利用する例
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// CRC-32のためのキャッシュテーブルを作成する関数 --- (*1) | |
fn crc32_table() -> [u32; 256] { | |
// テーブルを0で初期化 | |
let mut table: [u32; 256] = [0; 256]; | |
let crc32poly:u32 = 0xEDB88320; | |
// 0-255の各値について繰り返し計算を行う --- (*2) | |
for i in 0..256 { | |
let mut crc:u32 = i as u32; // 値を初期化 | |
// 8回(8ビット分)繰り返す --- (*4) | |
for _ in 0..8 { | |
if (crc & 1) == 1 { | |
crc >>= 1; | |
crc ^= crc32poly; | |
} else { | |
crc >>= 1; | |
} | |
} | |
table[i] = crc; | |
// キャッシュテーブルの内容を分かりやすく出力 | |
print!("0x{:08X},", table[i]); | |
if i % 8 == 7 { | |
println!(""); | |
} | |
} | |
table | |
} | |
// キャッシュテーブルを用いてCRC-32を計算する関数 --- (*5) | |
fn crc32_update(bin_data: &[u8], cache_table: &[u32; 256]) -> u32 { | |
// CRC-32の初期値 | |
let mut crc:u32 = 0xFFFFFFFF; | |
// バイト列の各バイトについて繰り返し計算を行う | |
for byte in bin_data { | |
// キャッシュテーブルを用いて計算する --- (*6) | |
crc = (crc >> 8) ^ cache_table[((crc & 0xFF) ^ (*byte as u32)) as usize]; | |
} | |
// ビットを反転させる --- (*6) | |
crc ^ 0xFFFFFFFF | |
} | |
fn main() { | |
// b"hello"のCRC-32を計算する --- (*7) | |
let bin_data = b"hello"; | |
// キャッシュテーブルを作成 | |
let cache_table = crc32_table(); | |
// 計算 | |
let crc = crc32_update(bin_data, &cache_table); | |
println!("CRC-32: {:08X}", crc); | |
// 念のためテスト | |
assert_eq!(crc32_update(b"test", &cache_table), 0xD87F7E0C); | |
assert_eq!(crc32_update(b"hoge", &cache_table), 0x8B39E45A); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment