0

0

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

藏色散人

藏色散人

发布时间:2019-11-18 14:38:43

|

4026人浏览过

|

来源于segmentfault

转载

前言

最近在项目中遇到一个问题,当前用户分享一个邀请码给好友,好友根据邀请码注册成为新用户之后,则成为当前用户的下级,特定条件下,可以得到下级用户的一系列返利。这里要实现的就是根据当前用户的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;
}

思路介绍:

立即学习PHP免费学习笔记(深入)”;

设定一个盐值,$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位的邀请码。

白月生产企业订单管理系统GBK2.0  Build 080807
白月生产企业订单管理系统GBK2.0 Build 080807

请注意以下说明:1、本程序允许任何人免费使用。2、本程序采用PHP+MYSQL架构编写。并且经过ZEND加密,所以运行环境需要有ZEND引擎支持。3、需要售后服务的,请与本作者联系,联系方式见下方。4、本程序还可以与您的网站想整合,可以实现用户在线服务功能,可以让客户管理自己的信息,可以查询自己的订单状况。以及返点信息等相关客户利益的信息。这个功能可提高客户的向心度。安装方法:1、解压本系统,放在

下载

再次探索

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

 '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 '';
            }
            $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('85U43DM');

结果:

12

总结

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

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

php

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

3

2025.12.31

php网站源码教程大全
php网站源码教程大全

本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

1

2025.12.31

视频文件格式
视频文件格式

本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

5

2025.12.31

不受国内限制的浏览器大全
不受国内限制的浏览器大全

想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

7

2025.12.31

出现404解决方法大全
出现404解决方法大全

本专题整合了404错误解决方法大全,阅读专题下面的文章了解更多详细内容。

30

2025.12.31

html5怎么播放视频
html5怎么播放视频

想让网页流畅播放视频?本合集详解HTML5视频播放核心方法!涵盖<video>标签基础用法、多格式兼容(MP4/WebM/OGV)、自定义播放控件、响应式适配及常见浏览器兼容问题解决方案。无需插件,纯前端实现高清视频嵌入,助你快速打造现代化网页视频体验。

3

2025.12.31

关闭win10系统自动更新教程大全
关闭win10系统自动更新教程大全

本专题整合了关闭win10系统自动更新教程大全,阅读专题下面的文章了解更多详细内容。

2

2025.12.31

阻止电脑自动安装软件教程
阻止电脑自动安装软件教程

本专题整合了阻止电脑自动安装软件教程,阅读专题下面的文章了解更多详细教程。

3

2025.12.31

html5怎么使用
html5怎么使用

想快速上手HTML5开发?本合集为你整理最实用的HTML5使用指南!涵盖HTML5基础语法、主流框架(如Bootstrap、Vue、React)集成方法,以及无需安装、直接在线编辑运行的平台推荐(如CodePen、JSFiddle)。无论你是新手还是进阶开发者,都能轻松掌握HTML5网页制作、响应式布局与交互功能开发,零配置开启高效前端编程之旅!

2

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 8.1万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 6.9万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号