国产哈希算法WJLHA(四):自定义哈希长度的WJLHA3开源(C\C++)

博客提及WJLHA3编码原理和唯一性证明可查看相关内容,还给出了算法源码,包括WJLHA3.h、WJLHA3.c文件,以及C语言下的测试文件main.c。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

完整数学证明请参看:

WJLHA3编码原理和唯一性证明

算法源码

文件名:WJLHA3.h

/**************************************************************************
 * Based on Weighted Probability Model Code(Jielin Code) And <Hash Algorithm with Adaptive Hash Value Length Based on Weighted Probability Model>
 * @author JieLin Wang(China)
 * @copyright JieLin Wang 2022-01-10
 * @Version 3.0.1
 * @email 254908447@qq.com
 */
#ifndef _WJLHA3_h
#define _WJLHA3_h
#include "math.h"
#include "memory.h"
#include "stdlib.h"
#include <stdio.h>
/*************************************************************************************
the main Wang Jie lin hash function
InBytesBuFF: the first address of bytes cache waiting to be encoding.
InBytesBuFF_Length: the bytes cache length.
HashValueBuFF:the hash value Byte Buff.
HashValueBuFF_Length: the hash value's byte length, by user-defined or system-defined.
*************************************************************************************/
void WJLHA3(unsigned char *InBytesBuFF,unsigned int InBytesBuFF_Length, unsigned char *HashValueBuFF,unsigned int HashValueBuFF_Length);

#endif

文件名:WJLHA3.c

#include "WJLHA3.h"
// Jielincode Encoding Struct
typedef struct
{
	unsigned int RC_CODE_BITS;
	unsigned int RC_SHIFT_BITS;
	unsigned int RC_MAX_RANGE;
	unsigned int RC_MIN_RANGE;
	double JIELINCOE;
	unsigned int EFLow;
	unsigned int EFRange;
	unsigned int EFDigits;
	unsigned int EFFollow;
	unsigned int EOut_buff_loop;
	unsigned char *HashValueBuFF;
	unsigned int HashValueBuFF_Length;
	unsigned int InBytesBuFF_Length;
}WJLCoder;
// Obtain a sequence X and obtain a weighted coefficient---JIELINCODE Coefficient
void TheCOE(WJLCoder *coder){
	// get the Jielin code coefficient
	coder->JIELINCOE = pow(   2.0, 1.0 - ( ((double)coder->HashValueBuFF_Length) / (double)coder->InBytesBuFF_Length )   );
}
// Output bytes to cache and weighted encoding
void OutPutByte(WJLCoder *coder, unsigned char ucByte)
{
	coder->HashValueBuFF[ coder->EOut_buff_loop % coder->HashValueBuFF_Length ] = coder->HashValueBuFF[ (coder->EOut_buff_loop + ucByte) % coder->HashValueBuFF_Length ] ^ ucByte;
	coder->EOut_buff_loop ++;
}
// Encode by JielinCeo
void Encode(WJLCoder *coder, unsigned char symbol)
{	
	unsigned int High = 0,i = 0;
	if (1 == symbol){// the Symbol 1
		coder->EFLow = coder->EFLow +  (unsigned int)((double)coder->EFRange * 0.5 * coder->JIELINCOE);
	}
	coder->EFRange = (unsigned int)((double)coder->EFRange * 0.5 * coder->JIELINCOE);
	while(coder->EFRange <= coder->RC_MIN_RANGE){
		High = coder->EFLow + coder->EFRange - 1;
		if(coder->EFFollow != 0) {
			if (High <= coder->RC_MAX_RANGE) {
				OutPutByte(coder, coder->EFDigits);
				for (i = 1; i <= coder->EFFollow - 1; ++i){
					OutPutByte(coder, 0xFF);
				}
				coder->EFFollow = 0;
				coder->EFLow = coder->EFLow + coder->RC_MAX_RANGE;
			} else if (coder->EFLow >= coder->RC_MAX_RANGE) {
				OutPutByte(coder, coder->EFDigits + 1);
				for (i = 1; i <= coder->EFFollow - 1; ++i){
					OutPutByte(coder, 0x00);
				}									
				coder->EFFollow = 0;
			} else {
				coder->EFFollow += 1;
				coder->EFLow = (coder->EFLow << 8) & (coder->RC_MAX_RANGE - 1);
				coder->EFRange = coder->EFRange << 8;
				continue;
			}
		}
		if  (((coder->EFLow ^ High) & (0xFF << coder->RC_SHIFT_BITS)) == 0) {
			OutPutByte(coder, (unsigned char)(coder->EFLow >> coder->RC_SHIFT_BITS));
		}else{
			coder->EFLow = coder->EFLow - coder->RC_MAX_RANGE;
			coder->EFDigits = coder->EFLow >> coder->RC_SHIFT_BITS;
			coder->EFFollow = 1;
		}
		coder->EFLow = ( ( (coder->EFLow << 8) & (coder->RC_MAX_RANGE - 1) ) | (coder->EFLow & coder->RC_MAX_RANGE) );
		coder->EFRange = coder->EFRange << 8;
	}
}
// Finish Encode by JielinCeo
void FinishEncode(WJLCoder *coder)
{
	unsigned int n = 0;
	if (coder->EFFollow != 0) {
		if (coder->EFLow < coder->RC_MAX_RANGE) {
			OutPutByte(coder, coder->EFDigits);
			for (n = 1; n <= coder->EFFollow - 1; n++) {
				OutPutByte(coder, 0xFF);
			}
		} else {
			OutPutByte(coder, coder->EFDigits + 1);
			for (n = 1; n <= coder->EFFollow - 1; n++) {
				OutPutByte(coder, 0x00);
			}
		}
	}
	coder->EFLow = coder->EFLow << 1;
	n = coder->RC_CODE_BITS + 1;
	do {
		n -= 8;
		OutPutByte(coder, (unsigned char)(coder->EFLow >> n));
	} while (!(n <= 0));
}
// Initialization WJLCoder
void InitializationWJLCoder(WJLCoder *coder)
{
	coder->RC_CODE_BITS = 31;
	coder->RC_SHIFT_BITS = coder->RC_CODE_BITS - 8;
	coder->RC_MAX_RANGE = 1 << coder->RC_CODE_BITS;
	coder->RC_MIN_RANGE = 1 << coder->RC_SHIFT_BITS;
	coder->JIELINCOE = 0.0;
	coder->EFLow = coder->RC_MAX_RANGE;
	coder->EFRange = coder->RC_MAX_RANGE;
	coder->EFDigits = 0;
	coder->EFFollow = 0;
	coder->EOut_buff_loop = 0;
	coder->HashValueBuFF_Length = 0;
}
// the main function
void WJLHA3(unsigned char *InBytesBuFF,unsigned int InBytesBuFF_Length, unsigned char *HashValueBuFF,unsigned int HashValueBuFF_Length)
{
	int i = 0, j = 0;
	WJLCoder *coder;
	// Less than 4 bytes are easily collided
	if(InBytesBuFF_Length < 4){
		return;
	}
	coder = (WJLCoder *)malloc(sizeof(WJLCoder));
	if(coder == NULL){
		return;
	}
	// Initialization WJLCoder Object
	InitializationWJLCoder(coder);
	coder->HashValueBuFF_Length = HashValueBuFF_Length;
	coder->HashValueBuFF  = (unsigned char *)malloc(HashValueBuFF_Length);
	memset(coder->HashValueBuFF, 0x00, HashValueBuFF_Length);
	coder->InBytesBuFF_Length = InBytesBuFF_Length;
	TheCOE(coder);
	// Up to 64 bits
	if(HashValueBuFF_Length >= 8){
		if(HashValueBuFF == NULL){
			HashValueBuFF = (unsigned char *)malloc(HashValueBuFF_Length);
		}
	}else{
		if(coder->HashValueBuFF) free(coder->HashValueBuFF);
		if(coder) free(coder);
		return;
	}
    // Encode each bits
	for(i = 0; i < InBytesBuFF_Length; ++i){
		for(j = 7; j >= 0; --j){
			Encode(coder, ((InBytesBuFF[i] >> j) & 0x01));
		}
	}
	if(InBytesBuFF_Length <= HashValueBuFF_Length){
		// Encode another 8L + 8 symbols 1
		for(i = 0; i < InBytesBuFF_Length + 1; ++i){
			for(j = 0; j < 8; ++j){
				Encode(coder, 0x01);
			}
		}
	}
	FinishEncode(coder);
	memcpy(HashValueBuFF, coder->HashValueBuFF, HashValueBuFF_Length);
	// Free memory
	if(coder->HashValueBuFF) free(coder->HashValueBuFF);
	if(coder) free(coder);
}

C语言下的测试:main.c

#include "WJLHA3.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include <math.h>
#ifdef WIN32
#define  inline __inline
#endif // WIN32
int main(){
	long t1,t2;
	int i = 0,j = 0, tmp = 0;
	unsigned int InBUFF_Length = 36;// The byte length entered
	unsigned int HashValueBuFF_Length = 16; // Customize the byte length of the output hash
	unsigned char *In_BUFF;
	unsigned char *HashValue_BUFF;
	// test
	unsigned char In_BUFFs[36]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9'};
	const char *In_BUFFs2 = "abcdefghijklmnopqrstuvwxyz你好!0123456789哈哈,测试";

	In_BUFF = (unsigned char *)malloc(InBUFF_Length);
	HashValue_BUFF = (unsigned char *)malloc(HashValueBuFF_Length);
	// Data of the InBUFF_Length length were randomly generated
	srand((unsigned)time(NULL));
	printf("\n");
	// get In_BUFFs2 Length
	InBUFF_Length = 0;
	while (In_BUFFs2[InBUFF_Length] != '\0') InBUFF_Length++;
	printf("%d\n", InBUFF_Length);
	for(i = 0; i < InBUFF_Length; ++i){
		In_BUFF[i] = In_BUFFs2[i];//rand() % 256;//(unsigned char)(i % 256);
		printf("%d ", In_BUFF[i]);
	}
	
	// WJLHA3
	printf("\n");
	t1 = GetTickCount();
	WJLHA3(In_BUFF, InBUFF_Length, HashValue_BUFF, HashValueBuFF_Length);
	t2 = GetTickCount();
	printf("Encoding takes time:%d ms\n", t2 - t1);
	printf("\nWJLHA String:");
	for(i = 0; i < HashValueBuFF_Length; ++i){
		printf("%02x",HashValue_BUFF[i]);
	}
	printf("\n");
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值