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

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

实现步骤

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

代码实现

下面是使用 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){ //撞库次数超过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)。
  • 随机性增强:可以在哈希值基础上添加时间戳、随机数等增强散列的随机性。
  • 更长哈希:使用不同的哈希算法或截取更多位数,可以增加散列的多样性。
相关推荐
kyle~15 分钟前
OpenCV---特征检测算法(ORB,Oriented FAST and Rotated BRIEF)
人工智能·opencv·算法
初学小刘23 分钟前
决策树:机器学习中的强大工具
算法·决策树·机器学习
nightunderblackcat23 分钟前
进阶向:人物关系三元组,解锁人物关系网络的钥匙
开发语言·python·开源·php
山顶风景独好25 分钟前
【Leetcode】随笔
数据结构·算法·leetcode
lxmyzzs2 小时前
【图像算法 - 16】庖丁解牛:基于YOLO12与OpenCV的车辆部件级实例分割实战(附完整代码)
人工智能·深度学习·opencv·算法·yolo·计算机视觉·实例分割
wow_DG3 小时前
【C++✨】多种 C++ 解法固定宽度右对齐输出(每个数占 8 列)
开发语言·c++·算法
Epiphany.5563 小时前
c++最长上升子序列长度
c++·算法·图论
Cx330❀3 小时前
【数据结构初阶】--排序(四):归并排序
c语言·开发语言·数据结构·算法·排序算法
余_弦4 小时前
区块链中的密码学 —— 密钥派生算法
算法·区块链
亲爱的非洲野猪4 小时前
令牌桶(Token Bucket)和漏桶(Leaky Bucket)细节对比
网络·算法·限流·服务