标题: 用VBS实现PHP的crc32函数
作者: Demon
链接: https://demon.tw/programming/vbs-php-crc32.html
版权: 本博客的所有文章,都遵守“署名-非商业性使用-相同方式共享 2.5 中国大陆”协议条款。
循环冗余校验(CRC)是一种根据网络数据封包或电脑档案等数据产生简短固定位数校验码的一种散列函數,主要用来检测或校验数据传输或者保存后可能出现的错误。生成的数字在传输或者储存之前计算出来并且附加到数据后面,然后接收方进行检验确定数据是否发生变化。一般来说,循环冗余校验的值都是32位的整数。由于本函数易于用二进制的电脑硬件使用、容易进行数学分析并且尤其善于检测传输通道干扰引起的错误,因此获得广泛应用。
昨天进行CRC校验的时候Google了一下CRC的介绍及原理,上面简单摘录了一段,更详细的介绍请访问维基百科。然后老毛病又犯了,怎样用VBS来实现CRC校验?
PHP有个crc32函数可以计算字符串的crc32值:
<?php $str = "The quick brown fox jumped over the lazy dog." $checksum = crc32($str); printf("%X\n", $checksum); ?>
下面是VBS版实现:
Option Explicit Dim crc32tab : crc32tab = Array( _ &H00000000, &H77073096, &Hee0e612c, &H990951ba, _ &H076dc419, &H706af48f, &He963a535, &H9e6495a3, _ &H0edb8832, &H79dcb8a4, &He0d5e91e, &H97d2d988, _ &H09b64c2b, &H7eb17cbd, &He7b82d07, &H90bf1d91, _ &H1db71064, &H6ab020f2, &Hf3b97148, &H84be41de, _ &H1adad47d, &H6ddde4eb, &Hf4d4b551, &H83d385c7, _ &H136c9856, &H646ba8c0, &Hfd62f97a, &H8a65c9ec, _ &H14015c4f, &H63066cd9, &Hfa0f3d63, &H8d080df5, _ &H3b6e20c8, &H4c69105e, &Hd56041e4, &Ha2677172, _ &H3c03e4d1, &H4b04d447, &Hd20d85fd, &Ha50ab56b, _ &H35b5a8fa, &H42b2986c, &Hdbbbc9d6, &Hacbcf940, _ &H32d86ce3, &H45df5c75, &Hdcd60dcf, &Habd13d59, _ &H26d930ac, &H51de003a, &Hc8d75180, &Hbfd06116, _ &H21b4f4b5, &H56b3c423, &Hcfba9599, &Hb8bda50f, _ &H2802b89e, &H5f058808, &Hc60cd9b2, &Hb10be924, _ &H2f6f7c87, &H58684c11, &Hc1611dab, &Hb6662d3d, _ &H76dc4190, &H01db7106, &H98d220bc, &Hefd5102a, _ &H71b18589, &H06b6b51f, &H9fbfe4a5, &He8b8d433, _ &H7807c9a2, &H0f00f934, &H9609a88e, &He10e9818, _ &H7f6a0dbb, &H086d3d2d, &H91646c97, &He6635c01, _ &H6b6b51f4, &H1c6c6162, &H856530d8, &Hf262004e, _ &H6c0695ed, &H1b01a57b, &H8208f4c1, &Hf50fc457, _ &H65b0d9c6, &H12b7e950, &H8bbeb8ea, &Hfcb9887c, _ &H62dd1ddf, &H15da2d49, &H8cd37cf3, &Hfbd44c65, _ &H4db26158, &H3ab551ce, &Ha3bc0074, &Hd4bb30e2, _ &H4adfa541, &H3dd895d7, &Ha4d1c46d, &Hd3d6f4fb, _ &H4369e96a, &H346ed9fc, &Had678846, &Hda60b8d0, _ &H44042d73, &H33031de5, &Haa0a4c5f, &Hdd0d7cc9, _ &H5005713c, &H270241aa, &Hbe0b1010, &Hc90c2086, _ &H5768b525, &H206f85b3, &Hb966d409, &Hce61e49f, _ &H5edef90e, &H29d9c998, &Hb0d09822, &Hc7d7a8b4, _ &H59b33d17, &H2eb40d81, &Hb7bd5c3b, &Hc0ba6cad, _ &Hedb88320, &H9abfb3b6, &H03b6e20c, &H74b1d29a, _ &Head54739, &H9dd277af, &H04db2615, &H73dc1683, _ &He3630b12, &H94643b84, &H0d6d6a3e, &H7a6a5aa8, _ &He40ecf0b, &H9309ff9d, &H0a00ae27, &H7d079eb1, _ &Hf00f9344, &H8708a3d2, &H1e01f268, &H6906c2fe, _ &Hf762575d, &H806567cb, &H196c3671, &H6e6b06e7, _ &Hfed41b76, &H89d32be0, &H10da7a5a, &H67dd4acc, _ &Hf9b9df6f, &H8ebeeff9, &H17b7be43, &H60b08ed5, _ &Hd6d6a3e8, &Ha1d1937e, &H38d8c2c4, &H4fdff252, _ &Hd1bb67f1, &Ha6bc5767, &H3fb506dd, &H48b2364b, _ &Hd80d2bda, &Haf0a1b4c, &H36034af6, &H41047a60, _ &Hdf60efc3, &Ha867df55, &H316e8eef, &H4669be79, _ &Hcb61b38c, &Hbc66831a, &H256fd2a0, &H5268e236, _ &Hcc0c7795, &Hbb0b4703, &H220216b9, &H5505262f, _ &Hc5ba3bbe, &Hb2bd0b28, &H2bb45a92, &H5cb36a04, _ &Hc2d7ffa7, &Hb5d0cf31, &H2cd99e8b, &H5bdeae1d, _ &H9b64c2b0, &Hec63f226, &H756aa39c, &H026d930a, _ &H9c0906a9, &Heb0e363f, &H72076785, &H05005713, _ &H95bf4a82, &He2b87a14, &H7bb12bae, &H0cb61b38, _ &H92d28e9b, &He5d5be0d, &H7cdcefb7, &H0bdbdf21, _ &H86d3d2d4, &Hf1d4e242, &H68ddb3f8, &H1fda836e, _ &H81be16cd, &Hf6b9265b, &H6fb077e1, &H18b74777, _ &H88085ae6, &Hff0f6a70, &H66063bca, &H11010b5c, _ &H8f659eff, &Hf862ae69, &H616bffd3, &H166ccf45, _ &Ha00ae278, &Hd70dd2ee, &H4e048354, &H3903b3c2, _ &Ha7672661, &Hd06016f7, &H4969474d, &H3e6e77db, _ &Haed16a4a, &Hd9d65adc, &H40df0b66, &H37d83bf0, _ &Ha9bcae53, &Hdebb9ec5, &H47b2cf7f, &H30b5ffe9, _ &Hbdbdf21c, &Hcabac28a, &H53b39330, &H24b4a3a6, _ &Hbad03605, &Hcdd70693, &H54de5729, &H23d967bf, _ &Hb3667a2e, &Hc4614ab8, &H5d681b02, &H2a6f2b94, _ &Hb40bbe37, &Hc30c8ea1, &H5a05df1b, &H2d02ef8d _ ) 'Author: Demon 'E-mail: 380401911@qq.com 'Website: https://demon.tw Function RShift(value, bit) Dim sc Set sc = CreateObject("MSScriptControl.ScriptControl") sc.Language = "JScript" RShift = sc.Eval(value & ">>" & bit) End Function Function crc32(str) Dim crc, length, i, p crc = 0 Xor &HFFFFFFFF length = LenB(str) For i = 1 To length p = MidB(str, i, 1) crc = (RShift(crc, 8) And &H00FFFFFF) _ Xor crc32tab((crc Xor AscB(p)) And &HFF) Next crc32 = crc Xor &HFFFFFFFF End Function Function UnicodeToUtf8(str) With CreateObject("adodb.stream") .Type = 2 : .Open : .Charset = "utf-8" .WriteText str : .Position = 0 .Type = 1 : .Position = 3 UnicodeToUtf8 = .Read : .Close End With End Function Dim str str = "The quick brown fox jumped over the lazy dog." WScript.Echo Hex(crc32(UnicodeToUtf8(str)))
输出的值和PHP一样。理论上校验文件的CRC只需要用ADODB.Stream读取文件的二进制值然后作为参数传递给crc32函数就行了,但是以前已经分析过了,像这样以字符串的形式处理二级制数据效率是很低的。于是用我知道的效率最高的方法重写了一个crc32_file函数:
'Author: Demon 'E-mail: 380401911@qq.com 'Website: https://demon.tw Function crc32_file(path) Dim crc, length, i crc = 0 Xor &HFFFFFFFF With CreateObject("adodb.stream") .Type = 1 : .Open .LoadFromFile path length = .Size - 1 Dim arr() : ReDim arr(length) For i = 0 To length crc = (RShift(crc, 8) And &H00FFFFFF) _ Xor crc32tab((crc Xor AscB(.Read(1))) And &HFF) Next .Close End With crc = crc Xor &HFFFFFFFF crc32_file = Hex(crc) End Function Dim t : t = Timer WScript.Echo crc32_file("bin") WScript.Echo Timer - t
但是即便是这样,计算一个1M文件的CRC32值也需要半分钟,而用昨天介绍的RapidCRC,也就一秒钟的事情。你优化,或者不优化,VBS的效率就在那里,不增不减,写这个程序只是拿来娱乐罢了。
赞赏微信赞赏支付宝赞赏
随机文章: