用VBS实现PHP的crc32函数

标签: , , , ,

循环冗余校验(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的效率就在那里,不增不减,写这个程序只是拿来娱乐罢了。

赞赏

微信赞赏支付宝赞赏

随机文章:

  1. VBS的一个BUG
  2. Windows下编译支持IPv6的Apache
  3. PT流量作弊工具之PTLiar
  4. JScript编辑器JsEdit
  5. Unable to find the socket transport "ssl" – did you forget to enable it when you configured PHP?

留下回复