void calc(const void* src, const int bytelength, unsigned char* hash) { // Init the result array. unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 }; // Cast the void src pointer to be the byte array we can work with. const unsigned char* sarray = (const unsigned char*) src; // The reusable round buffer unsigned int w[80]; // Loop through all complete 64byte blocks. const int endOfFullBlocks = bytelength - 64; int endCurrentBlock; int currentBlock = 0; while (currentBlock <= endOfFullBlocks) { endCurrentBlock = currentBlock + 64; // Init the round buffer with the 64 byte block data. for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4) { // This line will swap endian on big endian and keep endian on little endian. w[roundPos++] = (unsigned int) sarray[currentBlock + 3] | (((unsigned int) sarray[currentBlock + 2]) << 8) | (((unsigned int) sarray[currentBlock + 1]) << 16) | (((unsigned int) sarray[currentBlock]) << 24); } innerHash(result, w); } // Handle the last and not full 64 byte block if existing. endCurrentBlock = bytelength - currentBlock; clearWBuffert(w); int lastBlockBytes = 0; for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes) { w[lastBlockBytes >> 2] |= (unsigned int) sarray[lastBlockBytes + currentBlock] << ((3 - (lastBlockBytes & 3)) << 3); } w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3); if (endCurrentBlock >= 56) { innerHash(result, w); clearWBuffert(w); } w[15] = bytelength << 3; innerHash(result, w); // Store hash in result pointer, and make sure we get in in the correct order on both endian models. for (int hashByte = 20; --hashByte >= 0;) { hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff; } }
void calc(const void *src, const int bytelength, unsigned char *hash) { // Init the result array, and create references to the five unsigned integers for better readabillity. unsigned int result[5]={0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476,0xC3D2E1F0}; const unsigned char *sarray=(const unsigned char*)src; // The variables unsigned int w[80]; int j,i,i1; j=0; // Loop through all complete 64byte blocks. for(i=0,i1=64; i<=(bytelength-64); i=i1,i1+=64) { int k=0; for(j=i;j<i1;j+=4) { // This line will swap endian on big endian and keep endian on little endian. w[k++]=(unsigned int)sarray[j+3]|(((unsigned int)sarray[j+2])<<8)|(((unsigned int)sarray[j+1])<<16)|(((unsigned int)sarray[j])<<24); } innerHash(result,w); } // fill in reminder i1=bytelength-i; memset(w,0,sizeof(unsigned int)*16); for(j=0;j<i1;j++) { w[j>>2]|=(unsigned int)sarray[j+i]<<((3-(j&3))<<3); } w[j>>2]|=0x80<<((3-(j&3))<<3); if(i1>=56) { innerHash(result,w); memset(w,0,sizeof(unsigned int)*16); } w[15]=bytelength<<3; innerHash(result,w); // Store hash in result pointer, and make sure we get in in the correct order on both endian models. for(i=20;--i>=0;) { hash[i]=(result[i>>2]>>(((3-i)&0x3)<<3))&0xFF; } }