WJLHA1.0.1(java版本)源代码,欢迎专业人士使用和破解(碰撞技术)。郑重提醒:未经授权,严禁商用。
WJLHA1.0.1的C源码请点击下面的连接:
WJLHA1.0.1版本C源码
使用过MD5、SHA、SM3算法的朋友应该知道这个算法的价值。此次增加JAVA版本,以方便专业人员测试与学习。如遇疑问,请留言。JAVA与C版已实现互通,均可自定义,同一文件两个版本计算出的值相同。
哈希(Hash)算法(散列算法),数学领域叫单向散列函数或杂凑函数。本文提供的算法,感兴趣的可以自行推导到数据检错应用方法(类如CRC、奇偶校验的应用)。该类算法其中的一个应用方法如图:
WJLHA1.0.1算法的JAVA源码:
源代码包括了WJLHashAlgorithm.java欢迎测试。
/******************************************************************************
杰林码-散列算法-JAVA版本
理论来源《杰林码-加权概率模型单向散列函数》
代码实现:王杰林
时间:2020.05.07
版本号:V1.0.1
******************************************************************************/
public class WJLHashAlgorithm {
// 编码位长
private int RC_CODE_BITS = 31;
// 低位移去位长
private int RC_SHIFT_BITS = RC_CODE_BITS - 8;
// 区间范围的最大值(Rmax) & 0x00000000FFFFFFFFL目的是转成正数
private long RC_MAX_RANGE = Unsigned((int) (1 << RC_CODE_BITS));
// 区间范围的最小值(Rmin)
private long RC_MIN_RANGE = Unsigned((int) (1 << RC_SHIFT_BITS));
// 符号0和符号1的概率
double p0 = 0.0;
double p1 = 0.0;
// 杰林码系数
double JIELINCOE = 0.0;
// 初始化编码器值
long EFLow = RC_MAX_RANGE;
long EFRange = RC_MAX_RANGE;
int EFDigits = 0;
int EFFollow = 0;
int EOut_buff_loop = 0;
// 每个字节中比特1的个数
private short[] CntOfOneSymbol = {
0x00,0x01,0x01,0x02,0x01,0x02,0x02,0x03,0x01,0x02,0x02,0x03,0x02,0x03,0x03,0x04,
0x01,0x02,0x02,0x03,0x02,0x03,0x03,0x04,0x02,0x03,0x03,0x04,0x03,0x04,0x04,0x05,
0x01,0x02,0x02,0x03,0x02,0x03,0x03,0x04,0x02,0x03,0x03,0x04,0x03,0x04,0x04,0x05,
0x02,0x03,0x03,0x04,0x03,0x04,0x04,0x05,0x03,0x04,0x04,0x05,0x04,0x05,0x05,0x06,
0x01,0x02,0x02,0x03,0x02,0x03,0x03,0x04,0x02,0x03,0x03,0x04,0x03,0x04,0x04,0x05,
0x02,0x03,0x03,0x04,0x03,0x04,0x04,0x05,0x03,0x04,0x04,0x05,0x04,0x05,0x05,0x06,
0x02,0x03,0x03,0x04,0x03,0x04,0x04,0x05,0x03,0x04,0x04,0x05,0x04,0x05,0x05,0x06,
0x03,0x04,0x04,0x05,0x04,0x05,0x05,0x06,0x04,0x05,0x05,0x06,0x05,0x06,0x06,0x07,
0x01,0x02,0x02,0x03,0x02,0x03,0x03,0x04,0x02,0x03,0x03,0x04,0x03,0x04,0x04,0x05,
0x02,0x03,0x03,0x04,0x03,0x04,0x04,0x05,0x03,0x04,0x04,0x05,0x04,0x05,0x05,0x06,
0x02,0x03,0x03,0x04,0x03,0x04,0x04,0x05,0x03,0x04,0x04,0x05,0x04,0x05,0x05,0x06,
0x03,0x04,0x04,0x05,0x04,0x05,0x05,0x06,0x04,0x05,0x05,0x06,0x05,0x06,0x06,0x07,
0x02,0x03,0x03,0x04,0x03,0x04,0x04,0x05,0x03,0x04,0x04,0x05,0x04,0x05,0x05,0x06,
0x03,0x04,0x04,0x05,0x04,0x05,0x05,0x06,0x04,0x05,0x05,0x06,0x05,0x06,0x06,0x07,
0x03,0x04,0x04,0x05,0x04,0x05,0x05,0x06,0x04,0x05,0x05,0x06,0x05,0x06,0x06,0x07,
0x04,0x05,0x05,0x06,0x05,0x06,0x06,0x07,0x05,0x06,0x06,0x07,0x06,0x07,0x07,0x08
};
// 每个字节中各位置的比特值
private byte[][] bitOfByteTable = {
{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,1},{0,0,0,0,0,0,1,0},{0,0,0,0,0,0,1,1},{0,0,0,0,0,1,0,0},{0,0,0,0,0,1,0,1},{0,0,0,0,0,1,1,0},{0,0,0,0,0,1,1,1}, //0~7
{0,0,0,0,1,0,0,0},{0,0,0,0,1,0,0,1},{0,0,0,0,1,0,1,0},{0,0,0,0,1,0,1,1},{0,0,0,0,1,1,0,0},{0,0,0,0,1,1,0,1},{0,0,0,0,1,1,1,0},{0,0,0,0,1,1,1,1}, //8~15
{0,0,0,1,0,0,0,0},{0,0,0,1,0,0,0,1},{0,0,0,1,0,0,1,0},{0,0,0,1,0,0,1,1},{0,0,0,1,0,1,0,0},{0,0,0,1,0,1,0,1},{0,0,0,1,0,1,1,0},{0,0,0,1,0,1,1,1}, //16~23
{0,0,0,1,1,0,0,0},{0,0,0,1,1,0,0,1},{0,0,0,1,1,0,1,0},{0,0,0,1,1,0,1,1},{0,0,0,1,1,1,0,0},{0,0,0,1,1,1,0,1},{0,0,0,1,1,1,1,0},{0,0,0,1,1,1,1,1}, //24~31
{0,0,1,0,0,0,0,0},{0,0,1,0,0,0,0,1},{0,0,1,0,0,0,1,0},{0,0,1,0,0,0,1,1},{0,0,1,0,0,1,0,0},{0,0,1,0,0,1,0,1},{0,0,1,0,0,1,1,0},{0,0,1,0,0,1,1,1}, //32~39
{0,0,1,0,1,0,0,0},{0,0,1,0,1,0,0,1},{0,0,1,0,1,0,1,0},{0,0,1,0,1,0,1,1},{0,0,1,0,1,1,0,0},{0,0,1,0,1,1,0,1},{0,0,1,0,1,1,1,0},{0,0,1,0,1,1,1,1}, //40~47
{0,0,1,1,0,0,0,0},{0,0,1,1,0,0,0,1},{0,0,1,1,0,0,1,0},{0,0,1,1,0,0,1,1},{0,0,1,1,0,1,0,0},{0,0,1,1,0,1,0,1},{0,0,1,1,0,1,1,0},{0,0,1,1,0,1,1,1}, //48~55
{0,0,1,1,1,0,0,0},{0,0,1,1,1,0,0,1},{0,0,1,1,1,0,1,0},{0,0,1,1,1,0,1,1},{0,0,1,1,1,1,0,0},{0,0,1,1,1,1,0,1},{0,0,1,1,1,1,1,0},{0,0,1,1,1,1,1,1}, //56~63
{0,1,0,0,0,0,0,0},{0,1,0,0,0,0,0,1},{0,1,0,0,0,0,1,0},{0,1,0,0,0,0,1,1},{0,1,0,0,0,1,0,0},{0,1,0,0,0,1,0,1},{0,1,0,0,0,1,1,0},{0,1,0,0,0,1,1,1}, //64~71
{0,1,0,0,1,0,0,0},{0,1,0,0,1,0,0,1},{0,1,0,0,1,0,1,0},{0,1,0,0,1,0,1,1},{0,1,0,0,1,1,0,0},{0,1,0,0,1,1,0,1},{0,1,0,0,1,1,1,0},{0,1,0,0,1,1,1,1}, //72~79
{0,1,0,1,0,0,0,0},{0,1,0,1,0,0,0,1},{0,1,0,1,0,0,1,0},{0,1,0,1,0,0,1,1},{0,1,0,1,0,1,0,0},{0,1,0,1,0,1,0,1},{0,1,0,1,0,1,1,0},{0,1,0,1,0,1,1,1}, //80~87
{0,1,0,1,1,0,0,0},{0,1,0,1,1,0,0,1},{0,1,0,1,1,0,1,0},{0,1,0,1,1,0,1,1},{0,1,0,1,1,1,0,0},{0,1,0,1,1,1,0,1},{0,1,0,1,1,1,1,0},{0,1,0,1,1,1,1,1}, //88~95
{0,1,1,0,0,0,0,0},{0,1,1,0,0,0,0,1},{0,1,1,0,0,0,1,0},{0,1,1,0,0,0,1,1},{0,1,1,0,0,1,0,0},{0,1,1,0,0,1,0,1},{0,1,1,0,0,1,1,0},{0,1,1,0,0,1,1,1}, //96~103
{0,1,1,0,1,0,0,0},{0,1,1,0,1,0,0,1},{0,1,1,0,1,0,1,0},{0,1,1,0,1,0,1,1},{0,1,1,0,1,1,0,0},{0,1,1,0,1,1,0,1},{0,1,1,0,1,1,1,0},{0,1,1,0,1,1,1,1}, //104~111
{0,1,1,1,0,0,0,0},{0,1,1,1,0,0,0,1},{0,1,1,1,0,0,1,0},{0,1,1,1,0,0,1,1},{0,1,1,1,0,1,0,0},{0,1,1,1,0,1,0,1},{0,1,1,1,0,1,1,0},{0,1,1,1,0,1,1,1}, //112~119
{0,1,1,1,1,0,0,0},{0,1,1,1,1,0,0,1},{0,1,1,1,1,0,1,0},{0,1,1,1,1,0,1,1},{0,1,1,1,1,1,0,0},{0,1,1,1,1,1,0,1},{0,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1}, //120~127
{1,0,0,0,0,0,0,0},{1,0,0,0,0,0,0,1},{1,0,0,0,0,0,1,0},{1,0,0,0,0,0,1,1},{1,0,0,0,0,1,0,0},{1,0,0,0,0,1,0,1},{1,0,0,0,0,1,1,0},{1,0,0,0,0,1,1,1}, //128~135
{1,0,0,0,1,0,0,0},{1,0,0,0,1,0,0,1},{1,0,0,0,1,0,1,0},{1,0,0,0,1,0,1,1},{1,0,0,0,1,1,0,0},{1,0,0,0,1,1,0,1},{1,0,0,0,1,1,1,0},{1,0,0,0,1,1,1,1}, //136~143
{1,0,0,1,0,0,0,0},{1,0,0,1,0,0,0,1},{1,0,0,1,0,0,1,0},{1,0,0,1,0,0,1,1},{1,0,0,1,0,1,0,0},{1,0,0,1,0,1,0,1},{1,0,0,1,0,1,1,0},{1,0,0,1,0,1,1,1}, //144~151
{1,0,0,1,1,0,0,0},{1,0,0,1,1,0,0,1},{1,0,0,1,1,0,1,0},{1,0,0,1,1,0,1,1},{1,0,0,1,1,1,0,0},{1,0,0,1,1,1,0,1},{1,0,0,1,1,1,1,0},{1,0,0,1,1,1,1,1}, //152~159
{1,0,1,0,0,0,0,0},{1,0,1,0,0,0,0,1},{1,0,1,0,0,0,1,0},{1,0,1,0,0,0,1,1},{1,0,1,0,0,1,0,0},{1,0,1,0,0,1,0,1},{1,0,1,0,0,1,1,0},{1,0,1,0,0,1,1,1}, //160~167
{1,0,1,0,1,0,0,0},{1,0,1,0,1,0,0,1},{1,0,1,0,1,0,1,0},{1,0,1,0,1,0,1,1},{1,0,1,0,1,1,0,0},{1,0,1,0,1,1,0,1},{1,0,1,0,1,1,1,0},{1,0,1,0,1,1,1,1}, //168~175
{1,0,1,1,0,0,0,0},{1,0,1,1,0,0,0,1},{1,0,1,1,0,0,1,0},{1,0,1,1,0,0,1,1},{1,0,1,1,0,1,0,0},{1,0,1,1,0,1,0,1},{1,0,1,1,0,1,1,0},{1,0,1,1,0,1,1,1}, //176~183
{1,0,1,1,1,0,0,0},{1,0,1,1,1,0,0,1},{1,0,1,1,1,0,1,0},{1,0,1,1,1,0,1,1},{1,0,1,1,1,1,0,0},{1,0,1,1,1,1,0,1},{1,0,1,1,1,1,1,0},{1,0,1,1,1,1,1,1}, //184~191
{1,1,0,0,0,0,0,0},{1,1,0,0,0,0,0,1},{1,1,0,0,0,0,1,0},{1,1,0,0,0,0,1,1},{1,1,0,0,0,1,0,0},{1,1,0,0,0,1,0,1},{1,1,0,0,0,1,1,0},{1,1,0,0,0,1,1,1}, //192~199
{1,1,0,0,1,0,0,0},{1,1,0,0,1,0,0,1},{1,1,0,0,1,0,1,0},{1,1,0,0,1,0,1,1},{1,1,0,0,1,1,0,0},{1,1,0,0,1,1,0,1},{1,1,0,0,1,1,1,0},{1,1,0,0,1,1,1,1}, //200~207
{1,1,0,1,0,0,0,0},{1,1,0,1,0,0,0,1},{1,1,0,1,0,0,1,0},{1,1,0,1,0,0,1,1},{1,1,0,1,0,1,0,0},{1,1,0,1,0,1,0,1},{1,1,0,1,0,1,1,0},{1,1,0,1,0,1,1,1}, //208~215
{1,1,0,1,1,0,0,0},{1,1,0,1,1,0,0,1},{1,1,0,1,1,0,1,0},{1,1,0,1,1,0,1,1},{1,1,0,1,1,1,0,0},{1,1,0,1,1,1,0,1},{1,1,0,1,1,1,1,0},{1,1,0,1,1,1,1,1}, //216~223
{1,1,1,0,0,0,0,0},{1,1,1,0,0,0,0,1},{1,1,1,0,0,0,1,0},{1,1,1,0,0,0,1,1},{1,1,1,0,0,1,0,0},{1,1,1,0,0,1,0,1},{1,1,1,0,0,1,1,0},{1,1,1,0,0,1,1,1}, //224~231
{1,1,1,0,1,0,0,0},{1,1,1,0,1,0,0,1},{1,1,1,0,1,0,1,0},{1,1,1,0,1,0,1,1},{1,1,1,0,1,1,0,0},{1,1,1,0,1,1,0,1},{1,1,1,0,1,1,1,0},{1,1,1,0,1,1,1,1}, //232~239
{1,1,1,1,0,0,0,0},{1,1,1,1,0,0,0,1},{1,1,1,1,0,0,1,0},{1,1,1,1,0,0,1,1},{1,1,1,1,0,1,0,0},{1,1,1,1,0,1,0,1},{1,1,1,1,0,1,1,0},{1,1,1,1,0,1,1,1}, //240~247
{1,1,1,1,1,0,0,0},{1,1,1,1,1,0,0,1},{1,1,1,1,1,0,1,0},{1,1,1,1,1,0,1,1},{1,1,1,1,1,1,0,0},{1,1,1,1,1,1,0,1},{1,1,1,1,1,1,1,0},{1,1,1,1,1,1,1,1} //248~255
};
// 由于java中没有无符号整型运算,在这里采用模拟运算方式,经过与C++的无符号类型验证通过的
private long Unsigned(int value) {
long result = value;
if (value > 0xffffffffL) {
result = (value % 0xffffffffL) - 1;
} else if (value < 0) {
result = value + 0xffffffffL + 1;
}
if (result < 0) {
result = Unsigned((int) result);
}
return result;
}
// 将有符号字节转成无符号字节
public int Unsigned(byte value) {
int result = value;
if (value > 0xff) {
result = (value % 0xff) - 1;
} else if (value < 0) {
result = value + 0xff + 1;
}
if (result < 0) {
result = Unsigned((byte)result);
}
return result;
}
// 为了提高密钥的有效作用,对密钥进行一定的处理,并且返回变换后的系数
private void ChangeKeyt(int keyt)
{
if(keyt < 100000.0 && keyt > 0){
JIELINCOE = JIELINCOE - (1.0 / ((double)keyt + 100000.0));
}else if(keyt >= 100000.0){
JIELINCOE = JIELINCOE - (1.0 / (double)keyt);
}
}
// 统计InBuFF中符号0的概率,并根据符号0的概率以及ByteLength得出杰林码系数,此函数就是根据杰林码理论所得
private void GetJieLinCoeV(byte[] InBuFF, int ByteLength)
{
int i;
double Count1 = 0, CountAll = 0, H = 0;
// 首先是判断InBuFFLength 是不是大于等于 3 * ByteLength
CountAll = (double)InBuFF.length * 8;
// 统计符号0的个数
for(i = 0; i < InBuFF.length; ++i){
Count1 += (double)CntOfOneSymbol[Unsigned(InBuFF[i])];
}
// 求出符号0的概率p0和符号1的概率p1
p1 = Count1 / CountAll;
p0 = 1.0 - p1;
// 全0或全1的二进制序列需要进行预处理
if(p1 == 0.0){
p1 = 0.001;
p0 = 1.0 - p1;
}else if(p0 == 0.0){
p0 = 0.001;
p1 = 1.0 - p0;
}
// 求出标准熵
H = -p0 * (Math.log(p0)/Math.log(2.0))- p1 * (Math.log(p1)/Math.log(2.0));
// 求出能编码出比特长度为ByteLength * 8的杰林码系数,请参看我的理论《杰林码-加权概率模型单向散列函数》中的公式(2-14)
JIELINCOE = Math.pow( 2.0, H - ( (ByteLength - 4) * 8 ) / CountAll );
}
// 输出字节到缓存中
private void WEOutPutEncode(byte[] EOut_buff, int ucByte)
{
if (ucByte > 255) {
ucByte = ucByte & 0xFF;
}
if(EOut_buff_loop < EOut_buff.length) {
EOut_buff[ EOut_buff_loop] = (byte)ucByte;
EOut_buff_loop = EOut_buff_loop + 1;
}
}
// 核心编码
private void WEncode(byte symbol, byte[] EOut_buff)
{
long High = 0,i = 0;
// 根据加权概率模型理论,杰林码系数作用于符号0和符号1的概率
if (1 == symbol){// 符号1
EFLow += Unsigned((int)(EFRange * p0));
EFRange = Unsigned((int)(EFRange * p1));
}else{
EFRange = Unsigned((int)(EFRange * p0));
}
EFRange = Unsigned((int)((double)(EFRange * JIELINCOE)));
// 根据区间编码方式每次输出一个编码后的字节
while(EFRange <= RC_MIN_RANGE){
High = Unsigned((int) (EFLow + EFRange - 1));
if(EFFollow != 0) {
if (High <= RC_MAX_RANGE) {
WEOutPutEncode(EOut_buff, EFDigits);
for (i = 1; i <= EFFollow - 1; ++i){
WEOutPutEncode(EOut_buff, 0xFF);
}
EFFollow = 0;
EFLow = EFLow + RC_MAX_RANGE;
}
else if (EFLow >= RC_MAX_RANGE) {
WEOutPutEncode(EOut_buff, EFDigits + 1);
for (i = 1; i <= EFFollow - 1; ++i){
WEOutPutEncode(EOut_buff, 0x00);
}
EFFollow = 0;
} else {
EFFollow = EFFollow + 1;
EFLow = Unsigned((int)((EFLow << 8) & (RC_MAX_RANGE - 1)));
EFRange = Unsigned((int) (EFRange << 8));
continue;
}
}
if (((Unsigned((int) EFLow) ^ Unsigned((int) High)) & (0xFFL << RC_SHIFT_BITS)) == 0) {
WEOutPutEncode(EOut_buff, (int) (Unsigned((int) EFLow) >> RC_SHIFT_BITS));
}else{
EFLow = Unsigned((int) (EFLow - RC_MAX_RANGE));
EFDigits = (int) Unsigned((int) (EFLow >> RC_SHIFT_BITS));
EFFollow = 1;
}
EFLow = Unsigned((int) (((EFLow << 8) & (RC_MAX_RANGE - 1)) | (EFLow & RC_MAX_RANGE)));
EFRange = Unsigned((int) (EFRange << 8));
}
}
private void WFinishEncode(byte[] EOut_buff)
{
int n = 0;
// 输出剩余延迟数字
if (EFFollow != 0) {
if (EFLow < RC_MAX_RANGE) {
// 趋向下沿
WEOutPutEncode(EOut_buff, EFDigits);
for (n = 1; n <= EFFollow - 1; n++) {
WEOutPutEncode(EOut_buff, 0xFF);
}
} else {
// 趋向上沿
WEOutPutEncode(EOut_buff, EFDigits + 1);
for (n = 1; n <= EFFollow - 1; n++) {
WEOutPutEncode(EOut_buff, 0x00);
}
}
}
// 输出剩余编码
EFLow = Unsigned((int) (EFLow << 1));
n = RC_CODE_BITS + 1;// 32位
do {
n -= 8;// 每次减少8位
WEOutPutEncode(EOut_buff, (int) Unsigned((int) (EFLow >> n)));
} while (!(n <= 0));
}
// 杰林码哈希算法函数
public byte[] WJLHA(byte[] InBuFF,int keyt, byte[] OutBuFF, int ByteLength)
{
int i = 0, j = 0;
if(InBuFF.length <= 1){
return null;
}else {
// 计算当前InBuFF中符号0和符号1的概率
GetJieLinCoeV(InBuFF, ByteLength);
// 设定了密钥
if(keyt > 0){
ChangeKeyt(keyt);
}
// 直接进行编码
for(i = 0; i < InBuFF.length; ++ i){
// 每个字节有8比特
for(j = 0; j < 8; ++ j){
// 对当前的symbol进行编码
WEncode(bitOfByteTable[Unsigned(InBuFF[i])][j], OutBuFF);
}
}
// 结束编码
WFinishEncode(OutBuFF);
// 不足自定义输出长度ByteLength的补充符号0
if(EOut_buff_loop < ByteLength){
for(i = EOut_buff_loop; i < ByteLength; ++i){
WEOutPutEncode(OutBuFF, 0);
}
}
}
return OutBuFF;
}
// 测试
public static void main(String[] args) {
int i = 0;
int In_BUFF_Len = 20000; // 随机生成字节
int ByteLength = 32; // 自定义输出的字节长度,这里为256位
int keyt = 0; // 私有密钥
byte[] In_BUFF = new byte[In_BUFF_Len];
byte[] Out_BUFF = new byte[ByteLength];
// 随机生成In_BUFF_Len长度的(int) (Math.random() * 255);
for(i = 0; i < In_BUFF_Len; ++i){
In_BUFF[i] = (byte)(Math.random() * 255);
}
// 调用WJLHashAlgorithm算法
WJLHashAlgorithm wha = new WJLHashAlgorithm();
wha.WJLHA(In_BUFF, keyt, Out_BUFF, ByteLength);
System.out.print("有符号的WJLHA:");
for(i = 0; i < ByteLength; ++i){
System.out.print(Out_BUFF[i]+",");
}
System.out.println();
System.out.print("无符号的WJLHA:");
for(i = 0; i < ByteLength; ++i){
System.out.print(wha.Unsigned(Out_BUFF[i])+",");
}
System.out.println();
}
}