首先先对key计算sha1,取结果的前32bit,然后跟要加密整数进行异或,得到一个加密后的32bit结果
对结果分组:2bit | 6bit | 6bit | 6bit | 6bit | 6bit
各个组分别取名为:a0、a1、a2、a3、a4、a5
另定义一个长度64的字典数组
$dict=array('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',
'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',
'01','02','03');
将前面每个分组的值作为字典数组的下标,则加密结果为:$dict[a0].$dict[a1].$dict[a2].$dict[a3].$dict[a4].$dict[a5]
这样加密后的结果就是一个长度6-12的字符串,如果字典数组最后3个元素用其他单字符表示,那么结果就固定为6个字符的字符串。
由于初学php不久,对php的函数库不熟悉,求大侠帮忙实现下加密解密算法:
string encrypt(int id,string key)
int decrypt(string text,string key)
回复讨论(解决方案) echo encrypt(1234, 'abc'), php_eol;echo decrypt( '1tggsy', 'abc');function encrypt($id, $key) { $dict = array('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', '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', '-','=','*' ); $key = current(unpack('l', sha1($key, 1))); $id ^= $key; $t = str_split(sprintf('%036b', $id), 6); foreach($t as &$v) $v = $dict[bindec($v)]; return join($t);}function decrypt($s, $key) { $dict = array('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', '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', '-','=','*' ); $dict = array_flip($dict); foreach(str_split($s) as $c) $r[] = sprintf('%06b', $dict[$c]); $id = bindec(join($r)); $key = current(unpack('l', sha1($key, 1))); return $id ^ $key;}
1tggsy
1234
我自己也实现了加密过程,不过看起来就没那么优雅了,执行效率也低点,贴出来衬托下高手风范
$key_string = 'abc';function keytoint($key) { $key_sha1 = sha1 ( $key ); $first_char = $key_sha1 [0]; if (ord ( $first_char ) > 55) { return hexdec ( (hexdec ( $first_char ) & 7) . substr ( $key_sha1, 1, 7 ) ) | (- 2147483648); } else { return hexdec ( $key_sha1 ); }}function encrypt($num){ $dict = array('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','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','*','!'); $r1 = $num ^ keytoint ( $key_string ); $r2 = decbin ( $r1 ); $r3 = array ( bindec ( substr ( $r2, 0, 2 ) ), bindec ( substr ( $r2, 2, 6 ) ), bindec ( substr ( $r2, 8, 6 ) ), bindec ( substr ( $r2, 14, 6 ) ), bindec ( substr ( $r2, 20, 6 ) ), bindec ( substr ( $r2, 26, 6 ) ) ); return $dict [$r3 [0]] . $dict [$r3 [1]] . $dict [$r3 [2]] . $dict [$r3 [3]] . $dict [$r3 [4]] . $dict [$r3 [5]];}
算法实现之后,发觉在设计算法时,有个缺陷没考虑到,
由于仅仅是id与key异或,加密后的结果存在一定规律性,
比如
1234->1tggsy
1235->1tggsx
有没有什么好的办法打散下结果?
这个够乱的了吧 $id = 1234;$key = 'aaa';for($i=1; $i&$v) { $v = $dict[bindec($v)]; if($i == 0) shuffle($dict); } return join($t);}function decrypt($s, $key) { $dict = array('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', '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', '-','=','*' ); $m = array_search($s{0}, $dict); $n = $m >> 2; srand($n); shuffle($dict); $dict = array_flip($dict); foreach(str_split($s) as $i=>$c) { $r[] = sprintf('%06b', $i==0 ? $m&0x03 : $dict[$c]); } $id = bindec(join($r)); $key = current(unpack('l', substr(sha1($key, 1), $n))); return $id ^ $key;}
1234 4rhk4b 12341235 od2ln* 12351236 wqkf8u 12361237 6k=gvu 12371238 bxecr* 12381239 =w-aoi 12391240 iiq3e1 12401241 z6umma 12411242 wlcnd8 12421243 rizj*m 12431244 4rhk47 12441245 od2lnt 12451246 wqkf8z 12461247 6k=gvj 12471248 bxecre 12481249 =w-aop 12491250 iiq3et 12501251 z6ummp 12511252 wlcndu 12521253 rizj*p 12531254 4rhk4s 12541255 od2lns 12551256 wqkf84 12561257 6k=gvn 12571258 bxecrl 12581259 =w-aot 12591260 iiq3ex 12601261 z6umm1 12611262 wlcndd 12621263 rizj*s 12631264 4rhk4h 12641265 od2lnq 12651266 wqkf83 12661267 6k=gvg 12671268 bxecr5 12681269 =w-aoh 12691270 iiq3ep 12701271 z6ummc 12711272 wlcnde 12721273 rizj*6 12731274 4rhk4i 12741275 od2ln= 12751276 wqkf8u 12761277 6k=gvi 12771278 bxecr9 12781279 =w-aol 12791280 iiq3bi 12801281 z6umhg 12811282 wlcnay 12821283 rizj6d 12831284 4rhk3z 12841285 od2l*n 12851286 wqkfbp 12861287 6k=gzj 12871288 bxec=o 12881289 =w-aed 12891290 iiq3by 12901291 z6umh* 12911292 wlcnag 12921293 rizj6v 12931294 4rhk3f 12941295 od2l*e 12951296 wqkfbj 12961297 6k=gzm 12971298 bxec=n 12981299 =w-aew 12991300 iiq3bs 13001301 z6umhl 13011302 wlcna4 13021303 rizj6v 13031304 4rhk3u 13041305 od2l*v 13051306 wqkfbm 13061307 6k=gz* 13071308 bxec=- 13081309 =w-aea 13091310 iiq3bm 13101311 z6umhe 13111312 wlcnas 13121313 rizj6= 13131314 4rhk38 13141315 od2l*l 13151316 wqkfbs 13161317 6k=gz6 13171318 bxec=q 13181319 =w-aen 13191320 iiq3bo 13201321 z6umhv 13211322 wlcnau 13221323 rizj61 13231324 4rhk3k 13241325 od2l*p 13251326 wqkfbv 13261327 6k=gzw 13271328 bxec=h 13281329 =w-ae- 13291330 iiq3bs 13301331 z6umhj 13311332 wlcna9 1332
在你的设计中,第一节只有 2bit 有效位,所以可在其上再附加4bit信息
而0~15的随机数正好是4bit
算法中,这个随机数起到2个作用
1、调整 key
2、打乱字典
如果不怎么需要太强的保密性,位运算移位就足够了,省点cpu
楼主的解答超赞
加上随机数后,1个整数可对应16种结果,64^6种结果尽数用上,解密时也不用再判断是不是无效字符串了。
是楼主的解答超赞,打错啦
不打了