业务id转密文短链的一种实现思路
业务场景:
买家通过电商app下单后,会受到一条短信,短信内容中包括改订单详情页面的h5地址连接,因为是出现在短信中,所以对连接有要求:
1.尽量短;2.安全性考虑,订单在数据库中对应的自增主键id不能暴露出来;3. url中id加密串位数要固定
解决思路:
-
要满足第2条要求,肯定是要对id进行某种加密后来展现到url中,其实方法有很多,可以通过把10进制id转为高进制(比如36进制)串;也可以直接对id进行md5加密。但是转换高进制的方式会位数不固定,这样不符合第3个条件。直接md5加密太长不满足条件2。鉴于此,要继续往下深入思考一下了
-
在搜索引擎如此发达的时代,如果什么事情都想着自己去原创,那样会显得太傻,于是,当你当前所能想出的方案不能解决问题时候,那就去度娘或者谷歌吧
-
于是去度娘敲下“微博短链”,深深可以借鉴,先粘上微博中url短链算法思路及代码如下:
12345678910111213141516171819202122将长网址md5生成32位签名串,分为4段,每段8个字节;
对这四段循环处理,取8个字节,将他看成16进制串与0x3fffffff(30位1)与操作,即超过30位的忽略处理;
这30位分成6段,每5位的数字作为字母表的索引取得特定字符,依次进行获得6位字符串;
总的md5串可以获得4个6位串;取里面的任意一个就可作为这个长url的短url地址;
function shorturl($input) {
$base32 = array (
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
,
'g'
,
'h'
,
'i'
,
'j'
,
'k'
,
'l'
,
'm'
,
'n'
,
'o'
,
'p'
,
'q'
,
'r'
,
's'
,
't'
,
'u'
,
'v'
,
'w'
,
'x'
,
'y'
,
'z'
,
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
);
$hex = md5($input);
$hexLen = strlen($hex);
$subHexLen = $hexLen / 8;
$output = array();
for
($i = 0; $i < $subHexLen; $i++) {
$subHex = substr ($hex, $i * 8, 8);
$
int
= 0x3FFFFFFF & (1 * (
'0x'
.$subHex));
$
out
=
''
;
for
($j = 0; $j < 6; $j++) {
$val = 0x0000001F & $
int
;
$
out
.= $base32[$val];
$
int
= $
int
>> 5;
}
$output[] = $
out
;
}
return
$output;
}
- 看了之后,真是啧啧称赞,肯定就用这个思路了,但是需要稍稍改良一下,因为 这个加密后有6位,而我们要求5位,需要注意的事:要满足不同id加密后的唯一性(其实是尽量保持低碰撞率);他的短链可表示的连接数为32的6次方约等于10亿个,我们改成6位后至少也要可以表示这个量级。
废话少说,修改后的算法如下:1234567891011121314151617181920212223242526272829function shortUrl($id=
''
, $salt=
''
) {
$base64 = array (
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
,
'g'
,
'h'
,
'i'
,
'j'
,
'k'
,
'l'
,
'm'
,
'n'
,
'o'
,
'p'
,
'q'
,
'r'
,
's'
,
't'
,
'u'
,
'v'
,
'w'
,
'x'
,
'y'
,
'z'
,
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'A'
,
'B'
,
'C'
,
'D'
,
'E'
,
'F'
,
'G'
,
'H'
,
'I'
,
'J'
,
'K'
,
'L'
,
'M'
,
'N'
,
'O'
,
'P'
,
'Q'
,
'R'
,
'S'
,
'T'
,
'U'
,
'V'
,
'W'
,
'X'
,
'Y'
,
'Z'
);
$hex = md5($id.$salt);
$hexLen = strlen($hex);
$subHexLen = $hexLen / 8;
$output = array();
for
($i = 0; $i < $subHexLen; $i++) {
$subHex = substr ($hex, $i * 8, 8);
$
int
= 0x3FFFFFFF & (1 * (
'0x'
.$subHex));
$
out
=
''
;
for
($j = 0; $j < 5; $j++) {
$val = 0x0000003F & $
int
;
$val = $val % 62;
$
out
.= $base64[$val];
$
int
= $
int
>> 6;
}
$output[] = $
out
;
}
$
in
= 0x3 & (1 * (
'0x'
.substr($hex, 0, 1)));
return
$output[$
in
];
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步