计算字符串的自定义长度、自定义进制随机均匀短散列值

1 篇文章 0 订阅

要生成自定义长度、自定义进制的随机均匀短散列值,可以结合哈希函数和进制转换来实现。哈希函数可以将字符串映射为固定长度的二进制值,然后根据自定义的进制进行编码,生成你需要的短散列值。我们可以使用 PHP 来实现该功能,以下是具体的步骤:

实现步骤

  1. 输入字符串的哈希值:使用常见的哈希算法如 MD5 或 SHA-256 生成散列值。
  2. 转换哈希值为数字:将生成的哈希值转换为数字表示。
  3. 根据自定义进制转换:将数字转换为你想要的进制(例如 62 进制,包含数字、大小写字母)。
  4. 控制散列长度:生成的散列值可以根据需求来截断或补齐为特定长度。

代码实现

下面是使用 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){ //撞库次数超过100
            return false;
        }
        //返回数据
        return $strabbr;
    }

代码说明

  1. 字符表定义:我们使用 0123456789ABCDEFGHJKMNPQRSTUVWXY 作为 32 进制字符表,去除了I、L、O、Z四字母,(I、i、L、l与数字1相似,O、o与数字0相似,Z、z与数字2相似,1~F属于16进制常规范筹不宜删减);

  2. 哈希计算:我们使用 hash('sha256', $inputStr) 来计算输入字符串的 SHA-256 哈希值。由于 SHA-256 生成 64 位的十六进制数(256 位),我们可以选取前 15 位哈希值转成十进制,以确保数值足够大且不会溢出。

  3. 进制转换:将哈希值的十进制数字逐位转为 32 进制,通过 num % $base 计算余数,从而获得 32 进制字符,并将字符拼接到结果中。

  4. 结果处理:使用 str_pad() 来确保最终生成的短散列值具有指定的长度,不足的部分以 0 补齐。

运行结果

对于输入字符串 "example_string",生成了一个 8 位长度的 32 进制短散列值。

扩展

  • 更大进制:如果需要更高的进制,可以扩展字符集。例如支持 95 个可打印字符(ASCII)。
  • 随机性增强:可以在哈希值基础上添加时间戳、随机数等增强散列的随机性。
  • 更长哈希:使用不同的哈希算法或截取更多位数,可以增加散列的多样性。
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值