æ°ããããã°ã©ãã³ã°èšèªãèŠããããšæã£ããšãããããŸã§äœåºŠãèŠãããšã®ããããã°ã©ã ããã®èšèªã§äœã£ãŠã¿ãã®ããªã¹ã¹ã¡ã§ããä»åã¯ãä»ã§ããããããšããã§äœ¿ãããŠããäŒçµ±çãªãã§ãã¯ãµã ã§ããCRC-32ãRustã§å®è£ ããŠã¿ãŸãããã
CRC-32ã£ãŠäœã ã£ãïŒ
CRC-32ãšã¯ãããã¯ãŒã¯ããã¡ã€ã«ã®ããŒã¿ç Žæããªãããæ€åºã§ããç°¡åãªèšç®ã¢ã«ãŽãªãºã ã§ããCRCã®ååã¯ãCyclic Redundancy Check(å·¡ååé·æ€æ»)ãã®ç¥ã§ããæ¯èŒçã¢ã«ãŽãªãºã ã容æã§ãããªãããå¹çããããŒã¿ã®èª€ãæ€åºãã§ããŸãã
1961幎ã«å ¬éãããŠä»¥æ¥ãã€ãŒãµããããåçš®éä¿¡æ©åšã§åºãå©çšãããŠããŸãããªããå§çž®åœ¢åŒã®ZIPããç»åãã¡ã€ã«ã®PNGãªã©ã§æ¡çšãããŠããŸãããã®ãããç§ãã¡ã®çæŽ»ã«æ¬ ãããªãã¢ã«ãŽãªãºã ã®äžã€ãšèšããã§ãããã
Cèšèªã§æžããããææ¬ã«ã€ããŠ
ãããããCRCã«ã¯ãããããªããªãšãŒã·ã§ã³ãååšããŸãããZIPãPNGã§ã¯ãCRC-32ããšåŒã°ããæ¹åŒã䜿ãããŠããŸãã
ããã§ãGZIPãã©ãŒãããã解説ããRFC 1952ããPNGãã©ãŒãããã解説ããRFC 2083ã«ã¯ãCèšèªã®ãœãŒã¹ã³ãŒããæ²èŒãããŠããŸãã
次ã®ç»é¢ã¯ãRFC-2083ã®æ«å°Ÿã§åç §ãããŠããCRC-32ãèšç®ããCèšèªã®ã³ãŒãã§ãããã®ããã°ã©ã ã§ã¯ãæåã«CRCãèšç®ããããã®ããŒãã«ãäœæããŠãããŠããã®ããŒãã«ãçšããŠCRC-32ã®ãã§ãã¯ãµã ãæ±ããä»çµã¿ã®ãã®ãšãªã£ãŠããŸãããã®ç¹ã«ã€ããŠã¯ãåŸã»ã©è©³ãã解説ããŸãã
Rustã§å®è£ ããŠã¿ãã
ããã§ã¯ãããã±ãŒãžãããŒãžã£ãŒå Œãã«ãã·ã¹ãã ã®Cargoãå©çšããŠãããžã§ã¯ããäœæããŸãããã
mkdir program_crc32
cd program_crc32
cargo init
ãããšäžèšã®ãããªãã£ã¬ã¯ããªæ§æã®ãããžã§ã¯ããäœæãããŸãã
.
âââ Cargo.toml
âââ src
âââ main.rs
ãã®äžã«ãããmain.rsãããã¹ããšãã£ã¿ã§ç·šéããŸãã
CRC-32ãæãã·ã³ãã«ã«å®è£ ãããŠã¿ãã
ããã§ã¯ãCRC-32ãæãã·ã³ãã«ã«å®è£ ããŠã¿ãŸããããCRC-32ã®èšç®ã¯ä»¥äžã®æé ã§è¡ãããŸãã
(1) CRCã®åæå€ãšããŠ0xFFFFFFFFãæå®
(2) 察象ããŒã¿åã«ã€ããŠã1ãã€ããã€äžèšã®(2)ãã(6)ã®åŠçãè¡ã
(3) CRCãšå¯Ÿè±¡ãã€ãã®XORãæ±ããŠCRCãšãã
(4) 8å以äž(5)ãš(6)ãç¹°ãè¿ã
(5) ãããCRCã®äžäœ1ãããã1ãªãã°ãCRCå€ã0xEDB88320ã§XORæŒç®
(6) CRCãå³ãž1ãããã·ãã
(7) CRCã®ããããå転ãã
ãã®ããã«ããããã·ãããšXORæŒç®ãç¹°ãè¿ãã ãã§èšç®ã§ããŸãããšãŠãã·ã³ãã«ã«æ±ããããšãã§ããŸãã
ããããã®ãŸãŸå®è£ ããã®ã以äžã®ããã°ã©ã ã§ããmain.rsã«ããã°ã©ã ãèšè¿°ããŠã¿ãŸãããããã¡ãã«ãã¢ããããŠããŸãã
// CRC-32ãèšç®ãã颿°
fn crc32(bin_data: &[u8]) -> u32 {
let crc32poly:u32 = 0xEDB88320;
// CRC-32ã®åæå€ --- (*1)
let mut crc:u32 = 0xFFFFFFFF;
// ãã€ãåã®åãã€ãã«ã€ããŠç¹°ãè¿ãèšç®ãè¡ã --- (*2)
for byte in bin_data {
// XORãè¡ã --- (*3)
crc ^= *byte as u32;
// 8å(8ãããå)ç¹°ãè¿ã --- (*4)
for _ in 0..8 {
// ãã ãäžäœãããã1ãªãXORãã --- (*5)
if (crc & 1) == 1 {
crc >>= 1;
crc ^= crc32poly;
} else {
crc >>= 1;
}
}
}
// ããããå転ããã --- (*6)
crc ^ 0xFFFFFFFF
}
fn main() {
// b"hello"ã®CRC-32ãèšç®ãã --- (*7)
let bin_data = b"hello";
let crc = crc32(bin_data);
println!("CRC-32: {:08X}", crc);
}
ããã°ã©ã ãå®è¡ããã«ã¯ãäžèšã®ã³ãã³ããå®è¡ããŸãã
cargo run
ãããšã次ã®ç»é¢ã®ããã«ãçãã§ãã0x3610A686ã衚瀺ãããããšã§ãããã
ããã°ã©ã ã確èªããŠã¿ãŸãããã(ïŒ1)ã§ã¯CRC-32ã®åæå€ãšããŠ0xFFFFFFFFãäžããŸãããããŠã(ïŒ2)以éã§ã¯èª¿ã¹ãããã€ãåã«å¯ŸããŠç¹°ãè¿ã(ïŒ3)ã®ããã«XORæŒç®ãè¡ããŸãããããŠã(ïŒ4)8åãããã·ãããè¡ããŸãããã ãã(ïŒ5)ã®ããã«äžäœãããã1ã®ãšãã«ã¯ã0xEDB88320ãXORæŒç®ããŸãããããŠãæåŸã«(ïŒ6)ã§åããããå転ãããŸãã
(ïŒ7)ã§ã¯ããã¹ãã§ãã€ããªæååb"hello"ã®CRC-32ã®å€ãæ±ããŠç»é¢ã«åºåããŸãã
ãã£ãã·ã¥ããŒãã«ãå©çšããŠé«éã«CRC-32ãèšç®ããã
PNGãGZIPã®RFCã«æžãããŠããCèšèªã®ããã°ã©ã ã§ã¯ãçŽæ¥CRC-32ãèšç®ããã®ã§ã¯ãªããCRC-32ãèšç®ããããã®ãã£ãã·ã¥ããŒãã«ãçšæããŠãããã䜿ã£ãŠé«éã«CRC-32ãèšç®ããããã«ãªã£ãŠããŸããã
ããã§ã¯ããã£ãã·ã¥ããŒãã«ãçšæããŠèšç®ããããã«ãäžèšã®ããã°ã©ã ãæ¹è¯ããŠã¿ãŸããããåãããsrc/main.rsãã«äžèšã®ããã°ã©ã ãèšè¿°ããŸãããã¡ãã«ãã¢ããããŠããŸãã
// 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];
}
// ããããå転ããã
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);
}
ããã°ã©ã ãå®è¡ããã«ã¯ãäžèšã®ã³ãã³ããå®è¡ããŸãããããšäœæããããã·ã¥ããŒãã«ã®äžèЧã衚瀺ãããã®åŸã§ããã°ã©ã ã®å®è¡çµæã衚瀺ããŸãã
cargo run
ããã°ã©ã ã確èªããŠã¿ãŸãããããã®ããã°ã©ã ã®ãã€ã³ãã¯ãCRCã®8ãããåã®ç¹°ãè¿ãèšç®ããããããè¡ã£ããã£ãã·ã¥ããŒã¿ã®ããŒãã«ãçšæããŠãããšããéšåã§ãã
(ïŒ1)ã§ã¯ãã£ãã·ã¥ããŒãã«ãäœæãã颿°crc32_tableãå®çŸ©ããŸããããã§äœããã£ãã·ã¥ããŒãã«ã¯ã1ãã€ããã€åç §ãããã®ã§ããããã0-225ãŸã§ã®8ãããã®ç¯å²ã§ãã(ïŒ2)ã®ç¹°ãè¿ãã§256éãã®å€ãçšæããŸããäœæããããŒãã«ã®1ã€ã®å€ã¯ã(ïŒ4)ã§åå€ã8ååã®ç¹°ãè¿ãã§äœæãããã®ã§ãã
(ïŒ5)ã§ã¯ãã£ãã·ã¥ããŒãã«ãçšããŠãCRC-32ãèšç®ãã颿°crc32_updateãå®çŸ©ããŸãã(ïŒ6)ã§ã¯XORæŒç®ãšãã£ãã·ã¥ããŒãã«ã®å€ãå©çšããŠãCRC-32ãèšç®ããŸãã(ïŒ7)ã§ã¯ãå®éã«b"hello"ã®CRC-32ã®èšç®å€ã衚瀺ããŸãã
ã¡ãªã¿ã«ãCRC-32ã®ããŒãã«ãèšç®ããæéãªã©ã埮ã ãããã®ã§ãããäžèšã®ããã«èšç®æžã¿ã®CRC-32ã®ããŒãã«ãæåããé åã«æžã蟌ãã§ãããŠããããå©çšãããšããã¢ãããŒããèããããã§ãããã
const CRC32_TABLE: [u32; 256] = [
0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535,0x9E6495A3,
0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD,0xE7B82D07,0x90BF1D91,
0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D,0x6DDDE4EB,0xF4D4B551,0x83D385C7,
0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5,
0x3B6E20C8,0x4C69105E,0xD56041E4,0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,
0x35B5A8FA,0x42B2986C,0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59,
...
];
æ¢ã«é·ããªã£ãŠããŸã£ãã®ã§ãããã°ã©ã å šäœã確èªãããå Žåã¯ããã¡ãã®GitHubã確èªããŠã¿ãŠãã ããããã®ããŒãã«ãå©çšããŠCRC-32ãèšç®ããŸãã
ãŸãšã
以äžãä»åã¯CRC-32ãèšç®ããããã°ã©ã ãäœã£ãŠã¿ãŸããããã£ãã·ã¥ããŒãã«ã䜿ããªãå Žåãšäœ¿ãå Žåã§2ã€ã®ãã¿ãŒã³ãäœã£ãŠã¿ãŸãããCèšèªã®å®è£ ãšæ¯ã¹ãŠã¿ãŠããããã»ã©ä»£ãããªã䜿ããããšãåãã£ãããšã§ãããããŸãã颿°åŒã³åºãã®éãCèšèªã®å®è£ ã§ã¯ãã€ã³ãåã³é åãµã€ãºã®æå®ãå¿ èŠãšãªããŸãããRustã®ã¹ã©ã€ã¹(Slice)ã§ããã°ã¡ã¢ãªãµã€ãºãåãã£ãŠãããé åãµã€ãºã®æå®ãäžèŠã§ãå®å šã«å©çšã§ããããšãåãã£ãããšã§ãããã
èªç±åããã°ã©ããŒããããã¯ãã©ã«ãŠãããã°ã©ãã³ã°ã®æ¥œãããäŒããæŽ»åãããŠããã代衚äœã«ãæ¥æ¬èªããã°ã©ãã³ã°èšèªããªã§ããã ãããã¹ã鳿¥œããµã¯ã©ããªã©ã2001幎ãªã³ã©ã€ã³ãœãã倧è³å ¥è³ã2004幎床æªèžãŠãŒã¹ ã¹ãŒããŒã¯ãªãšãŒã¿èªå®ã2010幎 OSSè²¢ç®è ç« åè³ãæè¡æžãå€ãå·çããŠãããçŽè¿ã§ã¯ããå®è·µåãã¢ãããã Pythonã«ããã¢ã«ãŽãªãºã ã®æç§æž(ãã€ããåºç)ããã·ãŽããã¯ãã©ã PythonèªååŠçã®æç§æž(ãã€ããåºç)ããããã«äœ¿ãã!æ¥åã§å®è·µã§ãã! Pythonã«ããAIã»æ©æ¢°åŠç¿ã»æ·±å±€åŠç¿ã¢ããªã®ã€ããæ¹ TensorFlow2察å¿(ãœã·ã )ãããã³ã¬ã§ãã£ããåŠã¶Python(ãã€ããåºç)ããªã©ã


