hash 位运算 练习
hash 位运算
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
【以下代码仅做位运算的练习,算法本身不合理 php转译python】
从头到尾彻底解析Hash表算法_知识库_博客园 https://kb.cnblogs.com/page/189480/
#include <stdio.h> #include <ctype.h> //多谢citylove指正。 //crytTable[]里面保存的是HashString函数里面将会用到的一些数据,在prepareCryptTable //函数里面初始化 unsigned long cryptTable[0x500]; //以下的函数生成一个长度为0x500(合10进制数:1280)的cryptTable[0x500] void prepareCryptTable() { unsigned long seed = 0x00100001, index1 = 0, index2 = 0, i; for( index1 = 0; index1 < 0x100; index1++ ) { for( index2 = index1, i = 0; i < 5; i++, index2 += 0x100 ) { unsigned long temp1, temp2; seed = (seed * 125 + 3) % 0x2AAAAB; temp1 = (seed & 0xFFFF) << 0x10; seed = (seed * 125 + 3) % 0x2AAAAB; temp2 = (seed & 0xFFFF); cryptTable[index2] = ( temp1 | temp2 ); } } } //以下函数计算lpszFileName 字符串的hash值,其中dwHashType 为hash的类型, //在下面GetHashTablePos函数里面调用本函数,其可以取的值为0、1、2;该函数 //返回lpszFileName 字符串的hash值; unsigned long HashString( char *lpszFileName, unsigned long dwHashType ) { unsigned char *key = (unsigned char *)lpszFileName; unsigned long seed1 = 0x7FED7FED; unsigned long seed2 = 0xEEEEEEEE; int ch; while( *key != 0 ) { ch = toupper(*key++); seed1 = cryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2); seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3; } return seed1; } //在main中测试argv[1]的三个hash值: //./hash "arr/units.dat" //./hash "unit/neutral/acritter.grp" int main( int argc, char **argv ) { unsigned long ulHashValue; int i = 0; if ( argc != 2 ) { printf("please input two arguments/n"); return -1; } /*初始化数组:crytTable[0x500]*/ prepareCryptTable(); /*打印数组crytTable[0x500]里面的值*/ for ( ; i < 0x500; i++ ) { if ( i % 10 == 0 ) { printf("/n"); } printf("%-12X", cryptTable[i] ); } ulHashValue = HashString( argv[1], 0 ); printf("/n----%X ----/n", ulHashValue ); ulHashValue = HashString( argv[1], 1 ); printf("----%X ----/n", ulHashValue ); ulHashValue = HashString( argv[1], 2 ); printf("----%X ----/n", ulHashValue ); return 0;
'''
class hash_algo {
var $cryptTable = array();
function hash_algo() {
$seed = 0x00100001;
for($index1 = 0; $index1 < 0x100; $index1++) {
for($index2 = $index1, $i = 0; $i < 5; $i++, $index2 += 0x100) {
$seed = ($seed * 125 + 3) % 0x2AAAAB;
$temp1 = ($seed & 0xFFFF) << 0x10;
$seed = ($seed * 125 + 3) % 0x2AAAAB;
$temp2 = ($seed & 0xFFFF);
$this->cryptTable[$index2] = ($temp1 | $temp2);
}
}
}
function hash_init($lpszString, $dwHashType) {
$seed1 = 0x7FED7FED;
$seed2 = 0xEEEEEEEE;
for($i = 0, $l = strlen($lpszString); $i < $l; ++$i) {
$ch = ord(strtoupper($lpszString[$i]));
$seed1 = $this->cryptTable[($dwHashType << 8) + $ch] ^ ($seed1 + $seed2);
$seed2 = $ch + $seed1 + $seed2 + ($seed2 << 5) + 3;
}
return (float)(sprintf('%u', ($seed1)));
}
function hash_final($lpszString) {
$HASH_OFFSET = 0;
$HASH_A = 1;
$HASH_B = 2;
$nHash = $this->hash_init($lpszString, $HASH_OFFSET);
$nHashA = $this->hash_init($lpszString, $HASH_A);
$nHashB = $this->hash_init($lpszString, $HASH_B);
return array($nHash, $nHashA, $nHashB);
}
}
'''
class hash_algo:
def __init__(self, str):
self.str = str
self.table = []
self.res = []
self.hash_algo()
self.hash_final()
def hash_algo(self):
seed = 0x00100001
for i in range(0, 0x100, 1):
iii = i
for ii in range(0, 5, 1):
seed = (seed * 125 + 3) % 0x2AAAAB
temp1 = (seed & 0xFFFF) << 0x10
seed = (seed * 125 + 3) % 0x2AAAAB
temp2 = (seed & 0xFFFF)
iii += 0x100
self.table.append(temp1 | temp2)
def hash_int(self, offset):
seed1 = 0x7FED7FED
seed2 = 0xEEEEEEEE
len_ = len(self.str)
for i in range(0, len_, 1):
ch = ord(self.str[i].upper())
seed1 = self.table[(offset << 8) + ch] ^ (seed1 + seed2)
seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3
return seed1
def hash_final(self):
self.res = [self.hash_int(0), self.hash_int(1), self.hash_int(2)]
l = ['http://e.hbqnb.com/inews/TemLCU0nNsqjJLnMtNJ8qA.html', 'http://www.ijntv.cn/inews/wOd1hvV5-xtvB9KGi-dMnA.html']
for i in l:
a = hash_algo(i)
print(i)
print(a.res)
'''
& 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 (a & b) 输出结果 12 ,二进制解释: 0000 1100
| 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。 (a | b) 输出结果 61 ,二进制解释: 0011 1101
^ 按位异或运算符:当两对应的二进位相异时,结果为1 (a ^ b) 输出结果 49 ,二进制解释: 0011 0001
~ 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1 。~x 类似于 -x-1 (~a ) 输出结果 -61 ,二进制解释: 1100 0011,在一个有符号二进制数的补码形式。
<< 左移动运算符:运算数的各二进位全部左移若干位,由 << 右边的数字指定了移动的位数,高位丢弃,低位补0。 a << 2 输出结果 240 ,二进制解释: 1111 0000
>> 右移动运算符:把">>"左边的运算数的各二进位全部右移若干位,>> 右边的数字指定了移动的位数 a >> 2 输出结果 15 ,二进制解释: 0000 1111
'''

更多精彩