要生成自定义长度、自定义进制的随机均匀短散列值,可以结合哈希函数和进制转换来实现。哈希函数可以将字符串映射为固定长度的二进制值,然后根据自定义的进制进行编码,生成你需要的短散列值。我们可以使用 PHP 来实现该功能,以下是具体的步骤:
实现步骤
- 输入字符串的哈希值:使用常见的算法>哈希算法如 MD5 或 SHA-256 生成散列值。
- 转换哈希值为数字:将生成的哈希值转换为数字表示。
- 根据自定义进制转换:将数字转换为你想要的进制(例如 62 进制,包含数字、大小写字母)。
- 控制散列长度:生成的散列值可以根据需求来截断或补齐为特定长度。
代码实现
下面是使用 PHP 实现该逻辑的代码示例:
php">/*** 生成自定义长度的自定义进制随机均匀短散列值** @param string $inputStr 需要计算的字符串* @param int $len 指定散列值字符长度(可取1~32位),默认32位(2:显示0~1;4:显示0~3;8:显示0~7;10:显示0~9;16:显示0~F;32:显示0~V;64:显示0~/)...")* @param int $base 自定义的进制,默认16进制* @return string*/
public static function generateCustomShortHash($inputStr, $len=32, $base=16, $prefix='', $suffix='',$times=0){$md5 = strtoupper(md5($prefix.$inputStr.$suffix));$base_str = array ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y' );//去除了I、L、O、Z四字母,(I、i、L、l与数字1相似,O、o与数字0相似,Z、z与数字2相似,1~F属于16进制常规范筹不宜删减);$b_one = ceil(log($base,2));//每一位字符需要2进制字符长度$h_one = ceil($b_one/4);//每一位字符需要16进制字符长度$m_len = $b_one % 4;//非4的整数倍时高位丢弃,计算丢弃的位数if(ceil(($b_one * $len) / 4) > strlen($md5)){//需要总16进制字符长度超过最大字符长度return false;}for ($run_num=0; $run_num < 100; $run_num++) { $hex = isset($hex)?strtoupper(md5($hex)):$md5;$strabbr = '';for ($i = 0; $i < $len; $i++) {//循环每一位目标字符生成工作$subHex = substr($hex, $i*$h_one, $h_one);//按目标字符所需16进制字符长度进行截取$b1_str = ($h_one - 1) * 4 + ($m_len?:4);//生成二进制位运算的1字符数$b0_str = $m_len?(4-$m_len):0;//生成二进制位运算的0字符数$b_str = $m_len?str_repeat('0',$b0_str).str_repeat('1',$b1_str):str_repeat('1',$b1_str);//拼接二进制位运算的字符串$int = (bindec('0b'.$b_str)) & (hexdec('0x'.$subHex));//按位与保留有效位值$strabbr .= $base_str[$int];//从数组中获取对应字符}//存表逻辑if(Urlabbr::selectcount(['strabbr'=>$strabbr])==0){$urlabbr_data = ['str'=>$inputStrc,'strmd5'=>md5($inputStr),'strabbr'=>$strabbr,'run_num'=>$run_num+1,'views'=>0,'createtime'=>$times?:time(),'updatetime'=>$times?:time(),'switch'=>1,];Urlabbr::addid($urlabbr_data);break;}}if($run_num >= 100){ //撞库次数超过100return false;}//返回数据return $strabbr;}
代码说明
-
字符表定义:我们使用 0123456789ABCDEFGHJKMNPQRSTUVWXY 作为 32 进制字符表,去除了I、L、O、Z四字母,(I、i、L、l与数字1相似,O、o与数字0相似,Z、z与数字2相似,1~F属于16进制常规范筹不宜删减);
-
哈希计算:我们使用
hash('sha256', $inputStr)
来计算输入字符串的 SHA-256 哈希值。由于 SHA-256 生成 64 位的十六进制数(256 位),我们可以选取前 15 位哈希值转成十进制,以确保数值足够大且不会溢出。 -
进制转换:将哈希值的十进制数字逐位转为 32 进制,通过
num % $base
计算余数,从而获得 32 进制字符,并将字符拼接到结果中。 -
结果处理:使用
str_pad()
来确保最终生成的短散列值具有指定的长度,不足的部分以0
补齐。
运行结果
对于输入字符串 "example_string"
,生成了一个 8 位长度的 32 进制短散列值。