Skip to content

Instantly share code, notes, and snippets.

@kujirahand
Last active January 19, 2024 11:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kujirahand/691a6b57700e1919854810feb8ce1675 to your computer and use it in GitHub Desktop.
Save kujirahand/691a6b57700e1919854810feb8ce1675 to your computer and use it in GitHub Desktop.
CRC32を計算するプログラム - キャッシュテーブルを利用する例
// 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