热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

php利用32进制实现对id加密解密

最近在项目中遇到一个问题,当前用户分享一个邀请码给好友,好友根据邀请码注册成为新用户之后,则成为当前用户的下级,特定条件下,可以得到下级用户的一系列返利。
前言

最近在项目中遇到一个问题,当前用户分享一个邀请码给好友,好友根据邀请码注册成为新用户之后,则成为当前用户的下级,特定条件下,可以得到下级用户的一系列返利。这里要实现的就是根据当前用户的id,生成一个加密串,并且可以反向解密。经过不断的测试调整,终于得到了最后的结果。如:

id = 12 code = 85U43DM

初次实现

先上代码,如下:

/**
 * 加密解密用户邀请码,
 * @param unknown $string
 * @param string $action  encode|decode
 * @return string
 */
function endecodeUserId($string, $action = 'encode') {
    $startLen = 13;
    $endLen = 8;
    $coderes = '';
    #TOD 暂设定uid字符长度最大到9
    if ($action=='encode') {
        $uidlen = strlen($string);
        $salt = 'yourself_code';
        $codestr = $string.$salt;
        $encodestr = hash('md4', $codestr);
        $coderes = $uidlen.substr($encodestr, 5,$startLen-$uidlen).$string.substr($encodestr, -12,$endLen);
        $coderes = strtoupper($coderes);
    }elseif($action=='decode'){
        $strlen = strlen($string);
        $uidlen = $string[0];
        $coderes = substr($string, $startLen-$uidlen+1,$uidlen);
    }
    return  $coderes;
}

思路介绍:

设定一个盐值,$salt,和id拼接后组成一个新的字符串,该盐值可用于后期对邀请码进行安全校验。对该字符串进行md4加密(考虑到相比md5,md4速度更快,并且安全性也并不弱),得到$encodestr,对该字符串进行拆分,分为前后两部分,第一部分$startLen,13个字符串;第二部分$endLen,8个字符串。将$string,这里指传入的id,和$uidlen,混入前一部分字符串。因这里目前仅支持id最大长度为9,因此$uidlen长度为1,这样最后我们便得到了一个长度为22的字符串。

加密的过程中,我们实际上是把id的数值和id的长度,混入到了加密串中,加密的时候我们根据存入的这些信息找到对应的位置,即可得到id。

这里,我们对安全性并没有要求很高,为了使程序运行速度更快,因此在解密的时候并没有验证。

测试,对id加密:

echo endecodeUserId(12);

输出结果:

23471DC2352712F34D6780

测试,对邀请码解密

echo endecodeUserId('23471DC2352712F34D6780','decode');

输出结果:

12

得到的结果看上去并没有问题,但是实际测试中发现这样一个问题,对于普通用户可能会存在这种情况,好友发到他手机微信上一个邀请码,然后他想要用电脑进行注册,但他并不知道该怎么样把邀请码从手机传到电脑上或者嫌麻烦,这时候他就要在电脑开始手动输入邀请码了,天哪,22位啊,还是大写字母加数字混合,估计他要放弃注册了。

因此,我们进行了调整,改成7位的邀请码。

再次探索

这里是在写文章之前对方法进行了封装,还是直接先上代码

 '0123456789ABCDEFGHJKMNPQRSTVWXYZ',//不含ILOU
    );
    public function __construct($type='32')
    {
        $this->type = $type;
        $this->baseChar = self::$convertList[$type];
    }
    /**
     * 公用方法,数字进行进制转换
     * @param $num
     * @return string
     */
    private function _idToString($num){
        $str = '';
        while ($num!=0){
            $tmp = $num % $this->type;
            $str .= $this->baseChar[$tmp];
            $num = intval($num/$this->type);
        }
        return $str;
    }
    /**
     * @desc  im:十机制数转换成三十二进制数
     * @param (string)$char 三十二进制数
     * return 返回:十进制数
     */
    public function idToString($id){//10位内id 返回7位字母数字
        //数组 增加备用数值
        $id += self::INIT_NUM;
        //左补0 补齐10位
        $str = str_pad($id,10,'0',STR_PAD_LEFT);
        //按位 拆分 4 6位(32进制 4 6位划分)
        $num1 = intval($str[0].$str[2].$str[6].$str[9]);
        $num2 = intval($str[1].$str[3].$str[4].$str[5].$str[7].$str[8]);
        $str1 = $str2 = '';
        $str1 = $this->_idToString($num1);
        $str1 = strrev($str1);
        $str2 = $this->_idToString($num2);
        $str2 = strrev($str2);
        //4 补足 3 4位 U L
        return str_pad($str1,3,'U',STR_PAD_RIGHT).str_pad($str2,4,'L',STR_PAD_RIGHT);
    }
    /**
     * @desc  im:三十二进制数转换成十机制数
     * @param (string)$char 三十二进制数
     * return 返回:十进制数
     */
    public function stringToId($str){
        //1 清除 3 4 位补足位
        $str1 = trim(substr($str,0,3),'U');
        $str2 = trim(substr($str,3,4),'L');
        $num1 = $this->_stringToId($str1);
        $num2 = $this->_stringToId($str2);
        //补位拼接
        $str1 = str_pad($num1,4,'0',STR_PAD_LEFT);
        $str2 = str_pad($num2,6,'0',STR_PAD_LEFT);
        $id = ltrim($str1[0].$str2[0].$str1[1].$str2[1].$str2[2].$str2[3].$str1[2].$str2[4].$str2[5].$str1[3],'0');
        //减去 备用数值
        $id -= self::INIT_NUM;
        return $id;
    }
    /**
     * 公用方法字符串转数字
     * @param $str
     * @return float|int|string
     */
    private function _stringToId($str){
        //转换为数组
        $charArr = array_flip(str_split($this->baseChar));
        $num = 0;
        for ($i=0;$i<=strlen($str)-1;$i++)
        {
            $linshi = substr($str,$i,1);
            if(!isset($charArr[$linshi])){
                return &#39;&#39;;
            }
            $num += $charArr[$linshi]*pow($this->type,strlen($str)-$i-1);
        }
        return $num;
    }
}

思路介绍

在一位工作多年的大神的指导下,采用了这种方法。将id转化为固定长度的32进制字符串,并加上自己的算法。为什么这里采用32进制,而不是其他进制呢?32进制可以包含足够多的英文字符,生成的加密串看起来会更规范,另一方面,排除一些不容易识别的英文字符(这里排除ILOU),因此采用了32进制,而并没有采用36进制。

加密过程,方法idToString(),因考虑到刚开始id比较小的时候,转为32进制会出现比较多的0,看起来很不规范,因此设定一个初始值INIT_NUM,这个可以自定义。根据传过来的id,加上初始值后得到一个长度为10位的数值,将这个数值间隔位拆开分为长度为4位的$num1和长度为6位的$num2,两个数值分别转换为32进制,$num1转化后得到长度为3的字符串,不足的用U补足,$num2得到长度为4的字符串,不足的用L来补足。

解密则是逆操作,反向操作即可。

测试:生成

$obj = new convert(32);
$res1 = $obj->idToString(12);

结果:

85U43DM

解密:

$obj = new convert(32);
$res1 = $obj->stringToId(&#39;85U43DM&#39;);

结果:

12

总结

当然,即使最后的这个方法中也存在有不足的地方,比如在对加密数值拆分为2个num值的时候,用的方法就很不灵活,一旦修改解密的地方也要跟着变动。这里只是分享一个思路,欢迎大家批评指正。

以上就是php利用32进制实现对id加密解密的详细内容,更多请关注 第一PHP社区 其它相关文章!


推荐阅读
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 学习SLAM的女生,很酷
    本文介绍了学习SLAM的女生的故事,她们选择SLAM作为研究方向,面临各种学习挑战,但坚持不懈,最终获得成功。文章鼓励未来想走科研道路的女生勇敢追求自己的梦想,同时提到了一位正在英国攻读硕士学位的女生与SLAM结缘的经历。 ... [详细]
  • 近年来,大数据成为互联网世界的新宠儿,被列入阿里巴巴、谷歌等公司的战略规划中,也在政府报告中频繁提及。据《大数据人才报告》显示,目前全国大数据人才仅46万,未来3-5年将出现高达150万的人才缺口。根据领英报告,数据剖析人才供应指数最低,且跳槽速度最快。中国商业结合会数据剖析专业委员会统计显示,未来中国基础性数据剖析人才缺口将高达1400万。目前BAT企业中,60%以上的招聘职位都是针对大数据人才的。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 生成对抗式网络GAN及其衍生CGAN、DCGAN、WGAN、LSGAN、BEGAN介绍
    一、GAN原理介绍学习GAN的第一篇论文当然由是IanGoodfellow于2014年发表的GenerativeAdversarialNetworks(论文下载链接arxiv:[h ... [详细]
  • 无线认证设置故障排除方法及注意事项
    本文介绍了解决无线认证设置故障的方法和注意事项,包括检查无线路由器工作状态、关闭手机休眠状态下的网络设置、重启路由器、更改认证类型、恢复出厂设置和手机网络设置等。通过这些方法,可以解决无线认证设置可能出现的问题,确保无线网络正常连接和上网。同时,还提供了一些注意事项,以便用户在进行无线认证设置时能够正确操作。 ... [详细]
  • 本文介绍了游戏开发中的人工智能技术,包括定性行为和非定性行为的分类。定性行为是指特定且可预测的行为,而非定性行为则具有一定程度的不确定性。其中,追逐算法是定性行为的具体实例。 ... [详细]
  • 本文详细介绍了相机防抖的设置方法和使用技巧,包括索尼防抖设置、VR和Stabilizer档位的选择、机身菜单设置等。同时解释了相机防抖的原理,包括电子防抖和光学防抖的区别,以及它们对画质细节的影响。此外,还提到了一些运动相机的防抖方法,如大疆的Osmo Action的Rock Steady技术。通过本文,你将更好地理解相机防抖的重要性和使用技巧,提高拍摄体验。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 数字账号安全与数据资产问题的研究及解决方案
    本文研究了数字账号安全与数据资产问题,并提出了解决方案。近期,大量QQ账号被盗事件引起了广泛关注。欺诈者对数字账号的价值认识超过了账号主人,因此他们不断攻击和盗用账号。然而,平台和账号主人对账号安全问题的态度不正确,只有用户自身意识到问题的严重性并采取行动,才能推动平台优先解决这些问题。本文旨在提醒用户关注账号安全,并呼吁平台承担起更多的责任。令牌云团队对此进行了长期深入的研究,并提出了相应的解决方案。 ... [详细]
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
author-avatar
红台门
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有