前面介绍了 MD5 的实现,这里介绍一下 SHA-1 算法的实现。具体代码来自【参考1】。
和之前 MD5 程序有一些差别在于这个程序不是一次性将所有文件都放入内存中,而是放入一部分,计算一部分,再用中间结果继续计算下一部分。这样,再大的文件也可以正常处理。
#include <Uefi.h> #include <Library/UefiLib.h> #include <Library/ShellCEntryLib.h> #include <stdio.h> #include <stdlib.h> #include <wchar.h> #include <Protocol/EfiShell.h> #include <Library/ShellLib.h> #include <Library/MemoryAllocationLib.h> #include "sha1.h" #define BUFFERSIZE 2048 extern EFI_BOOT_SERVICES *gBS; extern EFI_SYSTEM_TABLE *gST; extern EFI_RUNTIME_SERVICES *gRT; extern EFI_SHELL_PROTOCOL *gEfiShellProtocol; int EFIAPI main ( IN int Argc, IN CHAR16 **Argv ) { EFI_FILE_HANDLE FileHandle; RETURN_STATUS Status; EFI_FILE_INFO *FileInfo = NULL; EFI_HANDLE *HandleBuffer=NULL; UINTN ReadSize=BUFFERSIZE; SHA1Context sha; //Check if there is a parameter if (Argc == 1) { Print(L"Usage: crctest [filename]\n"); return 0; } //Open the file given by the parameter Status = ShellOpenFileByName(Argv[1], (SHELL_FILE_HANDLE *)&FileHandle, EFI_FILE_MODE_READ , 0); if(Status != RETURN_SUCCESS) { Print(L"OpenFile failed!\n"); return EFI_SUCCESS; } //Get file size FileInfo = ShellGetFileInfo( (SHELL_FILE_HANDLE)FileHandle); /* * Reset the SHA-1 context and process input */ SHA1Reset(&sha); //Allocate a memory buffer HandleBuffer = AllocateZeroPool(BUFFERSIZE); if (HandleBuffer == NULL) { return (SHELL_OUT_OF_RESOURCES); } while (BUFFERSIZE == ReadSize) { ReadSize=BUFFERSIZE; //Load the whole file to the buffer Status = ShellReadFile(FileHandle,&ReadSize,HandleBuffer); SHA1Input(&sha,(unsigned char *) HandleBuffer, ReadSize); } //Output Print(L"File Name: %s\n",Argv[1]); Print(L"File Size: %d\n",(UINTN)FileInfo-> FileSize); if (!SHA1Result(&sha)) { Print(L"sha: could not compute message digest\n"); } else { Print(L"%08X %08X %08X %08X %08X\n", sha.Message_Digest[0], sha.Message_Digest[1], sha.Message_Digest[2], sha.Message_Digest[3], sha.Message_Digest[4]); } FreePool(HandleBuffer); return EFI_SUCCESS; }
运行结果:
完整的代码下载:
参考:
1.https://www.packetizer.com/