目前小弟使用的是一个国外下下来的crc32类模块源码如下。
因为在使用中要大量引用crc32校验,一次可以反复校验数据5000-30000组
所以效率问题自然也就得注重了。有几个想法,希望高人们指点指点
目的,校验byte数据而非文件
1,要是改成查表法是否要快些呢?我在网上试了一下查表法的crc16报错,不知哪位有查大表的crc32模块可用
2,如果将crc32类编译成activex dll再引用,效率会高些么?上面两个就是我的疑问了.....希望大家帮忙另外还有个问题就是交验结果值会存在顺序文件中
现在读取CRC值的顺序文件是使用的open再input N次到指定行来读取,换成api不知效率提高大不大.....如果不大当然为了程序的简洁性就不换了.
CRC值的顺序文件就是
45B3466A
4DAC3BAB
D991495D
E648A090
DE85329B
36D74691
AC22B962
86E80A7E
这样有5000-30000行的一个纯文本以下为crc32类模块Option ExplicitPrivate m_arrTable(0 To 255) As Long, m_lCheckSum As LongProperty Get Check() As String
    Dim arrData() As Byte, dTemp As Long, sTemp As String
    arrData = StrConv("123456789", vbFromUnicode)
    sTemp = Hex(Calculate(arrData))
    Check = String(8 - Len(sTemp), "0") & sTemp
End PropertyProperty Get CheckSum() As Long
    CheckSum = m_lCheckSum
End PropertyProperty Get Poly() As String
    Dim sTemp As String
    sTemp = Hex(&HEDB88320)
    Poly = String(8 - Len(sTemp), "0") & sTemp
End PropertyPrivate Function Calculate(arrData() As Byte) As Long
    Dim lCheckSum As Long, N As Long, lTemp1 As Long, lTemp2 As Long
    lCheckSum = &HFFFFFFFF
    For N = 0 To UBound(arrData)
        lTemp1 = ((lCheckSum And &HFFFFFF00) \ &H100) And &HFFFFFF
        lTemp2 = m_arrTable((lCheckSum And &HFF) Xor CLng(arrData(N)))
        lCheckSum = lTemp1 Xor lTemp2
    Next
    lCheckSum = lCheckSum Xor &HFFFFFFFF
    Calculate = lCheckSum
End FunctionFunction CRC(arrData() As Byte) As Long
    Dim lCheckSum As Long
    lCheckSum = Calculate(arrData)
    m_lCheckSum = lCheckSum
    CRC = Int(lCheckSum)
End FunctionPrivate Sub CreateTable()
    Dim N As Long, M As Long, lRegister As Long, lTemp As Long
    For N = 0 To 255
        lRegister = N
        For M = 0 To 7
            lTemp = ((lRegister And &HFFFFFFFE) \ &H2) And &H7FFFFFFF
            If lRegister And &H1 Then
                lRegister = lTemp Xor &HEDB88320
            Else
                lRegister = lTemp
            End If
        Next
        m_arrTable(N) = lRegister
    Next
End SubPrivate Sub Class_Initialize()
    CreateTable
End Sub

解决方案 »

  1.   

    有点郁闷同样的程序,只是校验部份换成了下面的代码,是csdn上一个朋友发的crc16的用我以前crc32的算法竟然比用这个crc16校验完一个400m文件快了30秒左右.为什么呢?下面那个是crc16并且还是查表的啊....怎么还会慢些呢.Option ExplicitPrivate HI16(0 To 255)  As Byte
    Private LO16(0 To 255)  As Byte
    Private bInited         As BooleanPublic Function CRC16(Data() As Byte) As Integer
        Dim CH              As Byte
        Dim CL              As Byte
        Dim C               As Byte
        Dim I               As Long    Call Init
        
        CH = &HFF: CL = &HFF    For I = LBound(Data) To UBound(Data)
            C = CH Xor Data(I)
            CH = CL Xor HI16(C)
            CL = LO16(C)
        Next I    'CRC16 = MakeWord(CL, CH)
        If CH And &H80 Then
            CRC16 = ((CH * &H100&) + CL) Or &HFFFF0000
        Else
            CRC16 = (CH * &H100&) + CL
        End If
    End FunctionPrivate Sub Init()
        If Not bInited Then
            InitArray HI16, _
                    &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, _
                    &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, _
                    &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, _
                    &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, _
                    &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, _
                    &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, _
                    &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, _
                    &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, _
                    &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, _
                    &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, _
                    &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, _
                    &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, _
                    &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, _
                    &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, _
                    &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40, &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, _
                    &H0, &HC1, &H81, &H40, &H1, &HC0, &H80, &H41, &H1, &HC0, &H80, &H41, &H0, &HC1, &H81, &H40
            InitArray LO16, _
                    &H0, &HC0, &HC1, &H1, &HC3, &H3, &H2, &HC2, &HC6, &H6, &H7, &HC7, &H5, &HC5, &HC4, &H4, _
                    &HCC, &HC, &HD, &HCD, &HF, &HCF, &HCE, &HE, &HA, &HCA, &HCB, &HB, &HC9, &H9, &H8, &HC8, _
                    &HD8, &H18, &H19, &HD9, &H1B, &HDB, &HDA, &H1A, &H1E, &HDE, &HDF, &H1F, &HDD, &H1D, &H1C, &HDC, _
                    &H14, &HD4, &HD5, &H15, &HD7, &H17, &H16, &HD6, &HD2, &H12, &H13, &HD3, &H11, &HD1, &HD0, &H10, _
                    &HF0, &H30, &H31, &HF1, &H33, &HF3, &HF2, &H32, &H36, &HF6, &HF7, &H37, &HF5, &H35, &H34, &HF4, _
                    &H3C, &HFC, &HFD, &H3D, &HFF, &H3F, &H3E, &HFE, &HFA, &H3A, &H3B, &HFB, &H39, &HF9, &HF8, &H38, _
                    &H28, &HE8, &HE9, &H29, &HEB, &H2B, &H2A, &HEA, &HEE, &H2E, &H2F, &HEF, &H2D, &HED, &HEC, &H2C, _
                    &HE4, &H24, &H25, &HE5, &H27, &HE7, &HE6, &H26, &H22, &HE2, &HE3, &H23, &HE1, &H21, &H20, &HE0, _
                    &HA0, &H60, &H61, &HA1, &H63, &HA3, &HA2, &H62, &H66, &HA6, &HA7, &H67, &HA5, &H65, &H64, &HA4, _
                    &H6C, &HAC, &HAD, &H6D, &HAF, &H6F, &H6E, &HAE, &HAA, &H6A, &H6B, &HAB, &H69, &HA9, &HA8, &H68, _
                    &H78, &HB8, &HB9, &H79, &HBB, &H7B, &H7A, &HBA, &HBE, &H7E, &H7F, &HBF, &H7D, &HBD, &HBC, &H7C, _
                    &HB4, &H74, &H75, &HB5, &H77, &HB7, &HB6, &H76, &H72, &HB2, &HB3, &H73, &HB1, &H71, &H70, &HB0, _
                    &H50, &H90, &H91, &H51, &H93, &H53, &H52, &H92, &H96, &H56, &H57, &H97, &H55, &H95, &H94, &H54, _
                    &H9C, &H5C, &H5D, &H9D, &H5F, &H9F, &H9E, &H5E, &H5A, &H9A, &H9B, &H5B, &H99, &H59, &H58, &H98, _
                    &H88, &H48, &H49, &H89, &H4B, &H8B, &H8A, &H4A, &H4E, &H8E, &H8F, &H4F, &H8D, &H4D, &H4C, &H8C, _
                    &H44, &H84, &H85, &H45, &H87, &H47, &H46, &H86, &H82, &H42, &H43, &H83, &H41, &H81, &H80, &H40
            bInited = True
        End If
    End SubPrivate Sub InitArray(Arr() As Byte, ParamArray Arg())
        Dim I               As Long
        
        For I = 0 To 255
            Arr(I) = Arg(I)
        Next
    End Sub
      

  2.   

    http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=9427&lngWId=1刚下到一个国外的,内嵌了汇编,速度快得吓人.....下午想办法改改提出来试了一下,同样一个400m文件,如果仅读出数据,写入空内容,也就是说同样流程,就是不进行crc运算,处理一个400文件需时20秒多一点使用我1楼发的crc32类需时80秒
    使用我2楼发的crc16模块需时120秒.
    国外这个....因为它本来是对整个文件进行运算的,所以还得改改才知道.
    下午,我改了后知道了结果再发上来.期待啊......如果能提到到50秒我也就心满意足了...
      

  3.   

    另补一句,在测试的程序中没有追求其它部份的效率,主要是为了方便,所以读取及写入全是用的open
    测试也主要是为了提高crc的效率,所以其它东东的效率在这里不考虑.
      

  4.   

    CRC 主要是位运算,适合硬件进行流处理,即每次输入 1 bit。其实,无论软硬件 CRC16 未必比 CRC32 快,软件查表法也不一定快,因为它的运算太简单了。VB 处理位运算毕竟比较笨拙,不如用 VC++ 写一个库。 
      

  5.   

    同意楼上,用 VC++ 做一个 Dll 还是不错的方案。
    注意给 VB 调用,输出函数要做一些处理。
    下面是我的源码:
    //[头文件]
    #ifdef __cplusplus
    #define DLLEXPORT extern "C" __declspec (dllexport)
    #else
    #define DLLEXPORT __declspec (dllexport)
    #endif//以下是为了减小编译后的PE文件体积而添加的预处理代码
    #ifndef _DEBUG
    #pragma comment(linker, "/FILEALIGN:16")
    #pragma comment(linker, "/ALIGN:16")
    #pragma comment(linker, "/OPT:NOWIN98")
    #endifvoid __stdcall InitializeCRC32Table();
    DWORD __stdcall GetByteArrayCRC32(BYTE*, LONG);
    DWORD __stdcall GetFileCRC32byHandle(HANDLE, LONG, LONG);
    DWORD __stdcall GetFileCRC32byName(LPCSTR, LONG, LONG);//[cpp 文件]
    #include "stdafx.h"
    #include "CRC32.h"
    #include "winbase.h"DWORD CRC32Table[256];
    BOOL APIENTRY DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved) 
    {
        switch (fdwReason) 
        {
        case DLL_PROCESS_ATTACH:
            InitializeCRC32Table();
            break;
        case DLL_PROCESS_DETACH:
        break;
        case DLL_THREAD_ATTACH:
        break;
        case DLL_THREAD_DETACH:
        break; 
    }
        return TRUE;
    }
    void __stdcall InitializeCRC32Table()
    {
    const DWORD Polynomial = 0xEDB88320;
        DWORD dwCRC32;
    LONG i, j; for(i = 0; i < 256; i++)
    {
    dwCRC32 = i;
    for(j = 8; j > 0; j--)
    {
    if(dwCRC32 & 1)
    dwCRC32 = (dwCRC32 >> 1) ^ Polynomial;
    else
    dwCRC32 >>= 1;
    }
    CRC32Table[i] = dwCRC32;
    }
    }
    DWORD __stdcall GetByteArrayCRC32(BYTE* pBuffer, LONG lLength) 
    {
    DWORD dwCRC32Result = 0xFFFFFFFF;
    BYTE* pCurrent = pBuffer;    while(lLength > 0)
    {
    dwCRC32Result = ((dwCRC32Result >> 8) & 0x00FFFFFF) ^ CRC32Table[(dwCRC32Result & 0xFF ^ *pCurrent)];
    pCurrent++;
    lLength--;
    }
    return dwCRC32Result;
    }
    DWORD __stdcall GetFileCRC32byHandle(HANDLE hFile, LONG lStartOffset, LONG lEndOffset) 
    {
    const DWORD BufferSize = 4096;
    BYTE byBuffer[BufferSize];

    DWORD nBytesResidual, nBytesDone = 0;
    DWORD nBytesRead; DWORD dwCRC32Result = 0xFFFFFFFF; LONG i; if(GetFileType(hFile) == FILE_TYPE_UNKNOWN)
    return 0xFFFFFFFF;

    SetFilePointer(hFile, lStartOffset, NULL, FILE_BEGIN);
    if(lEndOffset == NULL)
    lEndOffset = GetFileSize(hFile, NULL);
        
    do
    {
    nBytesResidual = lEndOffset - lStartOffset - nBytesDone;
    if(nBytesResidual <= BufferSize)
    {
    ReadFile(hFile, byBuffer, nBytesResidual, &nBytesRead, NULL);
    for(i = 0; (DWORD)i < nBytesResidual; i++)
    dwCRC32Result = ((dwCRC32Result >> 8) & 0x00FFFFFF) ^ CRC32Table[(dwCRC32Result & 0xFF ^ byBuffer[i])];
    break;
    }
    else
    {
    ReadFile(hFile, byBuffer, BufferSize, &nBytesRead, NULL);
    for(i = 0; i < BufferSize; i++)
    dwCRC32Result = ((dwCRC32Result >> 8) & 0x00FFFFFF) ^ CRC32Table[(dwCRC32Result & 0xFF ^ byBuffer[i])];
    nBytesDone += BufferSize;
    }
    }
    while(TRUE); return dwCRC32Result;
    }
    DWORD __stdcall GetFileCRC32byName(LPCSTR lpFileName, LONG lStartOffset, LONG lEndOffset) 
    {
    HANDLE hFile;
    DWORD dwCRC32Result = 0xFFFFFFFF; hFile = CreateFile(lpFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    if(hFile != INVALID_HANDLE_VALUE)
    {
    dwCRC32Result = GetFileCRC32byHandle(hFile, lStartOffset, lEndOffset);
    CloseHandle(hFile);
    } return dwCRC32Result;
    }
    //[def 文件]
    LIBRARY      "CRC32"
    DESCRIPTION  'CRC32 Windows Dynamic Link Library'EXPORTS
    GetByteArrayCRC32      @1
    GetFileCRC32byHandle   @2
    GetFileCRC32byName     @3
      

  6.   

    .....这个那个。。能不能直接QQ传或电邮呢?我的电邮是[email protected]
    因为偶完全不懂C所以。。给偶C的代码也没办法调试编译成DLL啊。-_-!
      

  7.   

    天啊。难以置信。
    用国外的那段,内嵌汇编的类模块使程序。。如飞一般,我当时差点傻了。
    同样结果的程序,校验同样的一个文件400mb用我一楼的类模块,需时86秒左右
    而且国外那个。。类模块,其它条件不变,竟然。只需时24秒!!!
    要知道我将crc运算去掉,仅使用open读出,再写入一个空字符来完成这个文件也需时20秒啊。
    我的妈啊!难以置信!经过我反复查看生成出来的crc组值,与用我1楼类模块生成出来的crc组值,一模一样。
    太恐怖了!!!!高兴死我了。