📄 sha.c
字号:
}/* Final wrapup - pad to SHA_DATASIZE-byte boundary with the bit pattern 1 0* (64-bit count of bits processed, MSB-first) */voidSHAFinal( char *key, SHA_CTX *shaInfo ){ int count; guint8 *dataPtr; /* Compute number of bytes mod 64 */ count = ( int ) shaInfo->countLo; count = ( count >> 3 ) & 0x3F; /* Set the first char of padding to 0x80. This is safe since there is always at least one byte free */ dataPtr = ( guchar * ) shaInfo->data + count; *dataPtr++ = 0x80; /* Bytes of padding needed to make 64 bytes */ count = SHA_DATASIZE - 1 - count; /* Pad out to 56 mod 64 */ if( count < 8 ) { /* Two lots of padding: Pad the first block to 64 bytes */ memset( dataPtr, 0, count ); longReverse( shaInfo->data, SHA_DATASIZE, shaInfo->Endianness ); SHATransform( shaInfo->digest, shaInfo->data ); /* Now fill the next block with 56 bytes */ memset( shaInfo->data, 0, SHA_DATASIZE - 8 ); } else /* Pad block to 56 bytes */ memset( dataPtr, 0, count - 8 ); /* Append length in bits and transform */ shaInfo->data[ 14 ] = shaInfo->countHi; shaInfo->data[ 15 ] = shaInfo->countLo; longReverse( shaInfo->data, SHA_DATASIZE - 8, shaInfo->Endianness ); SHATransform( shaInfo->digest, shaInfo->data ); longReverse(shaInfo->digest, SHA_DIGESTSIZE, shaInfo->Endianness ); g_memmove(key, shaInfo->digest, SHA_DIGESTSIZE);}/* ************************************************************ *//* Code below is David Helder's API for GNet */struct _GSHA{ SHA_CTX ctx; guchar digest[GNET_SHA_HASH_LENGTH];};/** * gnet_sha_new: * @buffer: Buffer to hash * @length: Length of that buffer * * Create an SHA hash of the buffer. * * Returns: a new #GSHA. * **/GSHA* gnet_sha_new (const guint8* buffer, guint length){ GSHA* gsha; gsha = g_new0 (GSHA, 1); SHAInit (&gsha->ctx); SHAUpdate (&gsha->ctx, buffer, length); SHAFinal ((gpointer) &gsha->digest, &gsha->ctx); return gsha;}/** * gnet_sha_new_string: * @str: Hexidecimal string * * Create an SHA hash from a hexidecimal string. The string must be * of length greater than or equal to %GNET_SHA_HASH_LENGTH * 2. * * Returns: a new #GSHA. * **/GSHA* gnet_sha_new_string (const gchar* str){ GSHA* gsha; guint i; g_return_val_if_fail (str, NULL); g_return_val_if_fail (strlen(str) == (GNET_SHA_HASH_LENGTH * 2), NULL); gsha = g_new0 (GSHA, 1); for (i = 0; i < (GNET_SHA_HASH_LENGTH * 2); ++i) { guint val = 0; switch (str[i]) { case '0': val = 0; break; case '1': val = 1; break; case '2': val = 2; break; case '3': val = 3; break; case '4': val = 4; break; case '5': val = 5; break; case '6': val = 6; break; case '7': val = 7; break; case '8': val = 8; break; case '9': val = 9; break; case 'A': case 'a': val = 10; break; case 'B': case 'b': val = 11; break; case 'C': case 'c': val = 12; break; case 'D': case 'd': val = 13; break; case 'E': case 'e': val = 14; break; case 'F': case 'f': val = 15; break; default: g_return_val_if_fail (FALSE, NULL); } if (i % 2) gsha->digest[i / 2] |= val; else gsha->digest[i / 2] = val << 4; } return gsha;}/** * gnet_sha_clone: * @gsha: SHA to clone. * * Create a SHA from another one. * * Returns: a new #GSHA. * **/GSHA* gnet_sha_clone (const GSHA* gsha){ GSHA* gsha2; g_return_val_if_fail (gsha, NULL); gsha2 = g_new0 (GSHA, 1); gsha2->ctx = gsha->ctx; memcpy (gsha2->digest, gsha->digest, sizeof(gsha->digest)); return gsha2;}/** * gnet_sha_delete: * @gsha: #GSHA to delete * * Delete a #GSHA. * **/voidgnet_sha_delete (GSHA* gsha){ if (gsha) g_free (gsha);}/** * gnet_sha_new_incremental: * * Create a SHA hash in incremental mode. After creating the #GSHA, call * gnet_sha_update() and gnet_sha_final(). * * Returns: new GSHA * **/GSHA* gnet_sha_new_incremental (void){ GSHA* gsha; gsha = g_new0 (GSHA, 1); SHAInit (&gsha->ctx); return gsha;}/** * gnet_sha_update: * @gsha: #GSHA to update * @buffer: Buffer to add * @length: Length of that buffer * * Update the hash with buffer. This may be called several times on * an incremental hash before being finalized. * **/voidgnet_sha_update (GSHA* gsha, const guchar* buffer, guint length){ g_return_if_fail (gsha); SHAUpdate (&gsha->ctx, buffer, length);}/** * gnet_sha_final: * @gsha: #GSHA to finalize * * Calcuate the final hash value. This is called on a #GSHA created * using gnet_sha_new_incremental() and updated using gnet_sha_update() * possibly several times. * **/voidgnet_sha_final (GSHA* gsha){ g_return_if_fail (gsha); SHAFinal ((gpointer) &gsha->digest, &gsha->ctx);}/* **************************************** *//** * gnet_sha_equal: * @p1: Pointer to first #GSHA. * @p2: Pointer to second #GSHA. * * Compare two #GSHA's. * * Returns: 1 if they are the same; 0 otherwise. * **/gintgnet_sha_equal (gconstpointer p1, gconstpointer p2){ GSHA* gshaa = (GSHA*) p1; GSHA* gshab = (GSHA*) p2; guint i; for (i = 0; i < GNET_SHA_HASH_LENGTH; ++i) if (gshaa->digest[i] != gshab->digest[i]) return 0; return 1;}/** * gnet_sha_hash * @p: GSHA to get hash value of * * Hash the GSHA hash value. This is not the actual SHA hash, but a * hash of this hash. * * Returns: hash value. * **/guintgnet_sha_hash (gconstpointer p){ const GSHA* gsha = (const GSHA*) p; const guint* q; g_return_val_if_fail (gsha, 0); q = (const guint*) gsha->digest; return (q[0] ^ q[1] ^ q[2] ^ q[3] ^ q[4]);}/** * gnet_sha_get_digest: * @gsha: #GSHA to get hash digest from * * Get the SHA hash digest. * * Returns: buffer containing the SHA hash digest. The buffer is * GNET_SHA_HASH_LENGTH bytes long. The #GSHA owns the buffer - do * not free it. * **/guint8* gnet_sha_get_digest (const GSHA* gsha){ g_return_val_if_fail (gsha, NULL); return (guint8*) gsha->digest;}static gchar bits2hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };/** * gnet_sha_get_string: * @gsha: #GSHA to get hash from * * Get a hash string. * * Returns: Hexadecimal string representing the hash. The string is * of length 2 * %GNET_SHA_HASH_LENGTH and null terminated. The * caller must free the string. * **/gchar* gnet_sha_get_string (const GSHA* gsha){ gchar* str; g_return_val_if_fail (gsha, NULL); str = g_new (gchar, GNET_SHA_HASH_LENGTH * 2 + 1); gnet_sha_copy_string (gsha, str); str[GNET_SHA_HASH_LENGTH * 2] = '\0'; return str;}/** * gnet_sha_copy_string: * @gsha: #GSHA to get hash from * @buffer: Buffer of length of at least 2 * %GNET_SHA_HASH_LENGTH * * Copy the hash string into the buffer. * **/voidgnet_sha_copy_string (const GSHA* gsha, guchar* buffer){ guint i; g_return_if_fail (gsha); g_return_if_fail (buffer); for (i = 0; i < GNET_SHA_HASH_LENGTH; ++i) { buffer[i * 2] = bits2hex[(gsha->digest[i] & 0xF0) >> 4]; buffer[(i * 2) + 1] = bits2hex[(gsha->digest[i] & 0x0F) ]; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -