//////////////////////////////////////////////////////////////////////// //預先處理 #include ///////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////// //全域變數 HWND g_hWnd; HINSTANCE g_hInst;
TCHAR szTemp[1024];
TCHAR szAppName[] = "CRC32 Sample"; /////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////// //函式宣告 DWORD GetCRC32(const BYTE *pbData, int nSize); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow); LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); /////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////// //主函數 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow) { MSG msg; WNDCLASSEX wndClassEx;
g_hInst = hInstance;
wndClassEx.cbSize = sizeof(WNDCLASSEX); wndClassEx.style = CS_VREDRAW | CS_HREDRAW; wndClassEx.lpfnWndProc = (WNDPROC) WindowProc; wndClassEx.cbClsExtra = 0; wndClassEx.cbWndExtra = 0; wndClassEx.hInstance = g_hInst; wndClassEx.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndClassEx.hCursor = LoadCursor(NULL, IDC_ARROW); wndClassEx.hbrBackground = (HBRUSH) (COLOR_WINDOW); wndClassEx.lpszMenuName = NULL; wndClassEx.lpszClassName = szAppName; wndClassEx.hIconSm = NULL;
RegisterClassEx(&wndClassEx);
g_hWnd = CreateWindowEx(0, szAppName, szAppName, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 300, 70, NULL, NULL, g_hInst, NULL);
ShowWindow(g_hWnd, iCmdShow); UpdateWindow(g_hWnd);
while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return ((int) msg.wParam); } ///////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////// //主視窗回呼函數 LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CREATE: CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_NOHIDESEL | WS_OVERLAPPED, 7, 12, 220, 22, hWnd, (HMENU)1000, g_hInst, NULL); CreateWindowEx(0, "BUTTON", "&OK", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_OVERLAPPED | BS_FLAT, 244, 12, 40, 20, hWnd, (HMENU)IDOK, g_hInst, NULL);
break;
case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: GetDlgItemText(g_hWnd, 1000, szTemp + 100, 800); wsprintf(szTemp, "當前文字框內的字串的CRC32校正碼是: 0x%lX", GetCRC32(szTemp + 100, (int)strlen(szTemp + 100))); MessageBox(g_hWnd, szTemp, szAppName, MB_OK|MB_ICONINformATION); } break;
case WM_DESTROY: PostQuitMessage(0); break;
default: return (DefWindowProc(hWnd, uMsg, wParam, lParam)); } return (0); } /////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////// //GetCRC32: 求位元組流的CRC32校正碼 //參數: // pbData: 指向位元組流緩衝區首地址 // nSize: 位元組流長度 // //傳回值: // 位元組流的CRC32校正碼 // //這裡使用查表法求CRC32校正碼,這部分是參考老羅的文章《 矛與盾的較量(2)——CRC原理篇》該寫的。 //原文的具體內容請參看: http://asp.7i24.com/netcool/laoluo/articles/show_article.asp?Article_ID=15 // //下面使用內聯彙編求CRC32校正碼,充分使用了CPU中的寄存器,速度和方便性都是使用C/C++所不能比擬的 // DWORD GetCRC32(const BYTE *pbData, int nSize) { DWORD dwCRC32Table[256];
__asm //這片內聯彙編是初始化CRC32表 { MOV ECX, 256
_NextTable: LEA EAX, [ECX-1] PUSH ECX MOV ECX, 8
_NextBit: SHR EAX, 1 JNC _NotCarry XOR EAX, 0xEDB88320 _NotCarry: DEC ECX JNZ _NextBit
POP ECX MOV [dwCRC32Table + ECX*4 - 4], EAX DEC ECX JNZ _NextTable }
__asm //下面是求CRC32校正碼 { MOV EAX, -1 MOV EBX, pbData OR EBX, EBX JZ _Done MOV ECX, nSize OR ECX, ECX JZ _Done
_NextByte: MOV DL, [EBX]
XOR DL, AL MOVZX EDX, DL SHR EAX, 8 XOR EAX, [dwCRC32Table + EDX*4]
INC EBX LOOP _NextByte _Done: NOT EAX } } //////////////////////////////////////////////////////////////////////////// |