可前端解密的加密方法探讨和str_replace和preg_replace分析
目的:
对字符串‘123456’进行后端加密,前端js可解密出真实字符
测试代码php:
static $hashMap = array( '0' => '4', '1' => '9', '2' => '1', '3' => '7', '4' => '2', '5' => '8', '6' => '3', '7' => '6', '8' => '5', '9' => '0', ); print_r(array_keys($hashMap));echo '==1=='; print_r(array_values($hashMap));echo '==2=='; $a = '123456'; echo str_replace(array_keys($hashMap), array_values($hashMap), $a);
输出结果:
Array ( [0] => 0 [1] => 1 [2] => 2 [3] => 3 [4] => 4 [5] => 5 [6] => 6 [7] => 7 [8] => 8 [9] => 9 ) ==1==Array ( [0] => 4 [1] => 9 [2] => 1 [3] => 7 [4] => 2 [5] => 8 [6] => 3 [7] => 6 [8] => 5 [9] => 0 ) ==2==016253
可见输出结果是:016253
而不是:917283
由此可见str_replace并不是对要替换的字符串依照数组对应关系进行一次性替换,而是根据替换的数组元素,对字符串的每个元素进行挨个替换,替换的字符串为上一次替换的结果
替换过程如下:
对0进行替换:123456
对1进行替换:923456
对2进行替换:913456 对3进行替换:917456 对4进行替换:917256 对5进行替换:917286 对6进行替换:917283 对7进行替换:916283 对8进行替换:916253 对9进行替换:016253
最终得到“016253”
preg_replace和str_replace替换规则一致,只是替换规则数组要改成正则方式:
static $hashMap = array( '/0/' => '4', '/1/' => '9', '/2/' => '1', '/3/' => '7', '/4/' => '2', '/5/' => '8', '/6/' => '3', '/7/' => '6', '/8/' => '5', '/9/' => '0', );
那如果想只是简单的按照加密序列值只进行单个字母或数字的一次性替换该怎么办?、
目前可以考虑用字符串循环的方式挨个替换一次,如下:
public static function mixHash($str=''){ static $hashMap = array( '0' => '4', '1' => '9', '2' => '1', '3' => '7', '4' => '2', '5' => '8', '6' => '3', '7' => '6', '8' => '5', '9' => '0', ); $b=''; for($i=0; $i<strlen($str); $i++){ if(isset($hashMap[substr($str, $i, 1)])){ $b .= (string)$hashMap[substr($str, $i, 1)]; }else{ $b .= (string)substr($str, $i, 1); } } return $b; }
对应前端可以进行反向解密:
function decodeHash(str){ str += ''; var hashMap = { '4': '0', '9': '1', '1': '2', '7': '3', '2': '4', '8': '5', '3': '6', '6': '7', '5': '8', '0': '9', }; var b = ''; for(var i=0;i<str.length;i++){ if(hashMap[str.substr(i,1)]){ b += hashMap[str.substr(i,1)] }else{ b += str.substr(i,1) } } return b; }
这样 123456 加密后就变成了:917283
这种方法较笨,而且加密效果不是很好,只是简单的混淆。
如果你有更好的方法,期待留言一起探讨~