⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shs.c

📁 雜湊法(Hashing)的搜尋與一般的搜尋法(searching)是不一樣的。在雜湊法中
💻 C
📖 第 1 页 / 共 2 页
字号:
	subRound( E, A, B, C, D, f4, K4, expand(shsInfo->data, 76) );
	subRound( D, E, A, B, C, f4, K4, expand(shsInfo->data, 77) );
	subRound( C, D, E, A, B, f4, K4, expand(shsInfo->data, 78) );
	subRound( B, C, D, E, A, f4, K4, expand(shsInfo->data, 79) );

	/* Build message digest */
	shsInfo->digest[ 0 ] += A;
	shsInfo->digest[ 1 ] += B;
	shsInfo->digest[ 2 ] += C;
	shsInfo->digest[ 3 ] += D;
	shsInfo->digest[ 4 ] += E;
}

#endif /* !ASM */

/* When run on a little-endian CPU we need to perform byte reversal on an
   array of longwords.  It is possible to make the code endianness-
   independant by fiddling around with data at the byte level, but this
   makes for very slow code, so we rely on the user to sort out endianness
   at compile time */

#ifdef LITTLE_ENDIAN
 
static void byteReverse( WORD32 *buffer, unsigned byteCount )
{
	WORD32 value;

	byteCount /= sizeof(WORD32);
	while ( byteCount-- ) {
		value = *buffer;
		value = ( value & 0xFF00FF00L ) >> 8  | \
		        ( value & 0x00FF00FFL ) << 8;
		*buffer++ = value << 16  |  value >> 16 ;
	}
}

#else /* !LITTLE_ENDIAN */

#define byteReverse(buf, count)	/* nothing */

#endif /* !LITTLE_ENDIAN */
 
/* Update SHS for a block of data. */
 
void shsUpdate( SHS_INFO *shsInfo, BYTE const *buffer, unsigned count )
{
	WORD32 t;

	/* Update bitcount */

#ifdef HAVE64
	t = ( (WORD32)shsInfo->count >> 3) & 0x3f;
	shsInfo->count += (WORD64)count << 3;
#else
	t = shsInfo->countLo;
	if ( ( shsInfo->countLo = t + ( (WORD32)count << 3) ) < t )
		shsInfo->countHi++;	/* Carry from low to high */
	shsInfo->countHi += count >> 29;

	t = (t >> 3) & 0x3f;	/* Bytes already in shsInfo->data */
#endif

	/* Handle any leading odd-sized chunks */

	if ( t ) {
		BYTE *p = (BYTE *)shsInfo->data + t;

		t = 64-t;
		if (count < t) {
			memcpy( p, buffer, count );
			return;
		}
		memcpy( p, buffer, t );
		byteReverse( shsInfo->data, SHS_BLOCKSIZE );
		shsTransform( shsInfo );
		buffer += t;
		count -= t;
	}

	/* Process data in SHS_BLOCKSIZE chunks */

	while( count >= SHS_BLOCKSIZE ) {
		memcpy( shsInfo->data, buffer, SHS_BLOCKSIZE );
		byteReverse( shsInfo->data, SHS_BLOCKSIZE );
		shsTransform( shsInfo );
		buffer += SHS_BLOCKSIZE;
		count -= SHS_BLOCKSIZE;
	}

	/* Handle any remaining bytes of data. */

	memcpy( shsInfo->data, buffer, count );
}

/* Final wrapup - pad to 64-byte boundary with the bit pattern 
   1 0* (64-bit count of bits processed, MSB-first) */
 
void shsFinal( SHS_INFO *shsInfo )
{
	int count;
	BYTE *p;

	/* Compute number of bytes mod 64 */
#ifdef HAVE64
	count = (int)shsInfo->count;
#else
	count = (int)shsInfo->countLo;
#endif
	count = ( count >> 3 ) & 0x3F;

	/* Set the first char of padding to 0x80.  This is safe since there is
	   always at least one byte free */
	p = (BYTE *)shsInfo->data + count;
	*p++ = 0x80;

	/* Bytes of padding needed to make 64 bytes */
	count = SHS_BLOCKSIZE - 1 - count;

	/* Pad out to 56 mod 64 */
	if( count < 8 ) {
		/* Two lots of padding:  Pad the first block to 64 bytes */
		memset( p, 0, count );
		byteReverse( shsInfo->data, SHS_BLOCKSIZE );
		shsTransform( shsInfo );

		/* Now fill the next block with 56 bytes */
		memset( shsInfo->data, 0, SHS_BLOCKSIZE - 8 );
	} else {
		/* Pad block to 56 bytes */
		memset( p, 0, count - 8 );
	}
	byteReverse( shsInfo->data, SHS_BLOCKSIZE-8 );

	/* Append length in bits and transform */
#if HAVE64
	shsInfo->data[ 14 ] = (WORD32)( shsInfo->count >> 32 );
	shsInfo->data[ 15 ] = (WORD32)shsInfo->count;
#else
	shsInfo->data[ 14 ] = shsInfo->countHi;
	shsInfo->data[ 15 ] = shsInfo->countLo;
#endif

	shsTransform( shsInfo );
}
 
/* ----------------------------- SHS Test code --------------------------- */
 
/* Size of buffer for SHS speed test data */
 
#define TEST_BLOCK_SIZE	( SHS_DIGESTSIZE * 100 )
 
/* Number of bytes of test data to process */
 
#define TEST_BYTES	10000000L
#define TEST_BLOCKS	( TEST_BYTES / TEST_BLOCK_SIZE )
 
void main( void )
{
	SHS_INFO shsInfo;
	BYTE data[ TEST_BLOCK_SIZE ];
	time_t endTime, startTime;
	long i;

	/* Test output data (this is the only test data given in the SHS
	   document, but chances are if it works for this it'll work for
	   anything) */
	shsInit( &shsInfo );
	shsUpdate( &shsInfo, (BYTE *)"abc", 3 );
	shsFinal( &shsInfo );
	if( shsInfo.digest[ 0 ] != 0x0164B8A9L || \
	    shsInfo.digest[ 1 ] != 0x14CD2A5EL || \
	    shsInfo.digest[ 2 ] != 0x74C4F7FFL || \
	    shsInfo.digest[ 3 ] != 0x082C4D97L || \
	    shsInfo.digest[ 4 ] != 0xF1EDF880L )
	{
		puts( "Error in SHS implementation: Test 1 failed" );
		exit( -1 );
	}
	puts("Test 1 passed");

	shsInit( &shsInfo );
	shsUpdate( &shsInfo, (BYTE *)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56 );
	shsFinal( &shsInfo );
	if( shsInfo.digest[ 0 ] != 0xD2516EE1L || \
	    shsInfo.digest[ 1 ] != 0xACFA5BAFL || \
	    shsInfo.digest[ 2 ] != 0x33DFC1C4L || \
	    shsInfo.digest[ 3 ] != 0x71E43844L || \
	    shsInfo.digest[ 4 ] != 0x9EF134C8L )
	{
		puts( "Error in SHS implementation: Test 2 failed" );
		exit( -1 );
	}
	puts("Test 2 passed");

	shsInit( &shsInfo );
	for( i = 0; i < 15625; i++ )
		shsUpdate( &shsInfo, (BYTE *)"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 64 );
	shsFinal( &shsInfo );
	if( shsInfo.digest[ 0 ] != 0x3232AFFAL || \
	    shsInfo.digest[ 1 ] != 0x48628A26L || \
	    shsInfo.digest[ 2 ] != 0x653B5AAAL || \
	    shsInfo.digest[ 3 ] != 0x44541FD9L || \
	    shsInfo.digest[ 4 ] != 0x0D690603L )
	{
		puts( "Error in SHS implementation: Test 3 failed" );
		exit( -1 );
	}
	puts("Test 3 passed");

	shsInit( &shsInfo );
	for( i = 0; i < 40000; i++ )
		shsUpdate( &shsInfo, (BYTE *)"aaaaaaaaaaaaaaaaaaaaaaaaa", 25 );
	shsFinal( &shsInfo );
	if( shsInfo.digest[ 0 ] != 0x3232AFFAL || \
	    shsInfo.digest[ 1 ] != 0x48628A26L || \
	    shsInfo.digest[ 2 ] != 0x653B5AAAL || \
	    shsInfo.digest[ 3 ] != 0x44541FD9L || \
	    shsInfo.digest[ 4 ] != 0x0D690603L )
	{
		puts( "Error in SHS implementation: Test 4 failed" );
		exit( -1 );
	}
	puts("Test 4 passed");

	shsInit( &shsInfo );
	for( i = 0; i < 8000; i++ )
		shsUpdate( &shsInfo, (BYTE *)"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 125 );
	shsFinal( &shsInfo );
	if( shsInfo.digest[ 0 ] != 0x3232AFFAL || \
	    shsInfo.digest[ 1 ] != 0x48628A26L || \
	    shsInfo.digest[ 2 ] != 0x653B5AAAL || \
	    shsInfo.digest[ 3 ] != 0x44541FD9L || \
	    shsInfo.digest[ 4 ] != 0x0D690603L )
	{
		puts( "Error in SHS implementation: Test 5 failed" );
		exit( -1 );
	}
	puts("Test 5 passed");

	/* Now perform time trial, generating MD for 10MB of data.  First,
	   initialize the test data */
	memset( data, 0, TEST_BLOCK_SIZE );

	/* Get start time */
	printf( "SHS time trial.  Processing %ld characters...\n", TEST_BYTES );
	time( &startTime );

	/* Calculate SHS message digest in TEST_BLOCK_SIZE byte blocks */
	shsInit( &shsInfo );
	for( i = TEST_BLOCKS; i > 0; i-- )
		shsUpdate( &shsInfo, data, TEST_BLOCK_SIZE );
	shsFinal( &shsInfo );

	/* Get finish time and time difference */
	time( &endTime );
	printf( "Seconds to process test input: %ld\n", endTime - startTime );
	printf( "Characters processed per second: %ld\n", TEST_BYTES / ( endTime - startTime ) );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -