1. 程式人生 > >php,js 對字符串按位異或運算加密解密

php,js 對字符串按位異或運算加密解密

字節 令行 UNC keys rep [] NPU 亂碼 按位或

異或的符號是^。按位異或運算, 對等長二進制模式按位或二進制數的每一位執行邏輯按位異或操作. 操作的結果是如果某位不同則該位為1, 否則該位為0.

xor運算的逆運算是它本身,也就是說兩次異或同一個數最後結果不變,即(a xor b) xor b = a。xor運算可以用於簡單的加密,比如我想對我MM說1314520,但怕別人知道,於是雙方約定拿我的生日19880516作為密鑰。1314520 xor 19880516 = 20665500,我就把20665500告訴MM。MM再次計算20665500 xor 19880516的值,得到1314520,於是她就明白了我的企圖。 相同位不同則為1,相同則為0。 00101 11100
(^或者xor) ---------------- 11001 運算結果 x <- x # y y <- x @ y x <- x @ y 執行了第一句後x變成了x # y。那麽第二句實質就是y <- x # y @ y,由於#和@互為逆運算,那麽此時的y變成了原來的x。第三句中x實際上被賦值為(x # y) @ x,如果#運算具有交換律,那麽賦值後x就變成最初的y了。這三句話的結果是,x和y的位置互換了。 通過這個原理運用PHP可實現簡單高效的加密 註意:
PHP語言的^運算符經常用來做加密的運算,解密也直接用^就行,但是和其他語言通信時,其他語言例如objective-c未必能解的出來PHP的^,尤其是當php使用多個字符串如:‘abc‘^‘def‘,這樣的運算時,其他語言少有這種直接可運算的,更不能解的出來
計算原理:
‘a‘^‘b‘ : a和b的ASCII分別為97和98,轉換2進制後分別為:1100001,1100010 然後使用此二位進行異或運算,得到結果:11 再用把二進制數11轉換為字符串 在windon命令行下計算結果會顯示一個亂碼

以下為實現方法:
<?php
$k = ‘app‘;
$v = ‘321‘;
echo ‘秘鑰:‘.$k;
echo ‘</br>‘;
echo ‘明文:‘.$v;
echo ‘</br>‘;
$key = sha1($k);
echo ‘sha1加密秘鑰:‘.$key;
echo
‘</br>‘; $yihuo = $v ^ $key; echo ‘異或運算:‘.$yihuo; echo ‘</br>‘; echo ‘base64_encode編碼:‘.base64_encode($yihuo); //按位異或運算加密 function xorencrypt( $str, $key ){ $slen = strlen( $str ); $klen = strlen( $key ); $cipher = ‘‘; for ($i=0;$i<$slen;$i=$i+$klen) { $cipher .= substr( $str, $i, $klen )^$key; } return $cipher; } //接收端實現簡單的解密 function xordecrypt( $str, $key ){ $slen = strlen( $str ); $klen = strlen( $key ); $plain = ‘‘; for ($i=0;$i<$slen;$i=$i+$klen) { $plain .= $key^substr( $str, $i, $klen ); } return $plain; } ?> <script> function encodeUTF8(s) { var i, r = [], c, x; for (i = 0; i < s.length; i++) if ((c = s.charCodeAt(i)) < 0x80) r.push(c); else if (c < 0x800) r.push(0xC0 + (c >> 6 & 0x1F), 0x80 + (c & 0x3F)); else { if ((x = c ^ 0xD800) >> 10 == 0) //對四字節UTF-16轉換為Unicode c = (x << 10) + (s.charCodeAt(++i) ^ 0xDC00) + 0x10000, r.push(0xF0 + (c >> 18 & 0x7), 0x80 + (c >> 12 & 0x3F)); else r.push(0xE0 + (c >> 12 & 0xF)); r.push(0x80 + (c >> 6 & 0x3F), 0x80 + (c & 0x3F)); }; return r; } // 字符串加密成 hex 字符串 function sha1(s) { var data = new Uint8Array(encodeUTF8(s)) var i, j, t; var l = ((data.length + 8) >>> 6 << 4) + 16, s = new Uint8Array(l << 2); s.set(new Uint8Array(data.buffer)), s = new Uint32Array(s.buffer); for (t = new DataView(s.buffer), i = 0; i < l; i++)s[i] = t.getUint32(i << 2); s[data.length >> 2] |= 0x80 << (24 - (data.length & 3) * 8); s[l - 1] = data.length << 3; var w = [], f = [ function () { return m[1] & m[2] | ~m[1] & m[3]; }, function () { return m[1] ^ m[2] ^ m[3]; }, function () { return m[1] & m[2] | m[1] & m[3] | m[2] & m[3]; }, function () { return m[1] ^ m[2] ^ m[3]; } ], rol = function (n, c) { return n << c | n >>> (32 - c); }, k = [1518500249, 1859775393, -1894007588, -899497514], m = [1732584193, -271733879, null, null, -1009589776]; m[2] = ~m[0], m[3] = ~m[1]; for (i = 0; i < s.length; i += 16) { var o = m.slice(0); for (j = 0; j < 80; j++) w[j] = j < 16 ? s[i + j] : rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1), t = rol(m[0], 5) + f[j / 20 | 0]() + m[4] + w[j] + k[j / 20 | 0] | 0, m[1] = rol(m[1], 30), m.pop(), m.unshift(t); for (j = 0; j < 5; j++)m[j] = m[j] + o[j] | 0; }; t = new DataView(new Uint32Array(m).buffer); for (var i = 0; i < 5; i++)m[i] = t.getUint32(i << 2); var hex = Array.prototype.map.call(new Uint8Array(new Uint32Array(m).buffer), function (e) { return (e < 16 ? "0" : "") + e.toString(16); }).join(""); return hex; } </script> <script> /** * * Base64 encode / decode * http://www.webtoolkit.info * **/ var Base64 = { // private property _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" // public method for encoding , encode: function (input) { var output = ""; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0; input = Base64._utf8_encode(input); while (i < input.length) { chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output = output + this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4); } // Whend return output; } // End Function encode // public method for decoding ,decode: function (input) { var output = ""; var chr1, chr2, chr3; var enc1, enc2, enc3, enc4; var i = 0; input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); while (i < input.length) { enc1 = this._keyStr.indexOf(input.charAt(i++)); enc2 = this._keyStr.indexOf(input.charAt(i++)); enc3 = this._keyStr.indexOf(input.charAt(i++)); enc4 = this._keyStr.indexOf(input.charAt(i++)); chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4; output = output + String.fromCharCode(chr1); if (enc3 != 64) { output = output + String.fromCharCode(chr2); } if (enc4 != 64) { output = output + String.fromCharCode(chr3); } } // Whend output = Base64._utf8_decode(output); return output; } // End Function decode // private method for UTF-8 encoding ,_utf8_encode: function (string) { var utftext = ""; string = string.replace(/\r\n/g, "\n"); for (var n = 0; n < string.length; n++) { var c = string.charCodeAt(n); if (c < 128) { utftext += String.fromCharCode(c); } else if ((c > 127) && (c < 2048)) { utftext += String.fromCharCode((c >> 6) | 192); utftext += String.fromCharCode((c & 63) | 128); } else { utftext += String.fromCharCode((c >> 12) | 224); utftext += String.fromCharCode(((c >> 6) & 63) | 128); utftext += String.fromCharCode((c & 63) | 128); } } // Next n return utftext; } // End Function _utf8_encode // private method for UTF-8 decoding ,_utf8_decode: function (utftext) { var string = ""; var i = 0; var c, c1, c2, c3; c = c1 = c2 = 0; while (i < utftext.length) { c = utftext.charCodeAt(i); if (c < 128) { string += String.fromCharCode(c); i++; } else if ((c > 191) && (c < 224)) { c2 = utftext.charCodeAt(i + 1); string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); i += 2; } else { c2 = utftext.charCodeAt(i + 1); c3 = utftext.charCodeAt(i + 2); string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3; } } // Whend return string; } // End Function _utf8_decode } </script> <script> function xor_enc(str, key) { var crytxt = ‘‘; var k, keylen = key.length; for(var i=0; i<str.length; i++) { k = i % keylen; crytxt += String.fromCharCode(str.charCodeAt(i) ^ key.charCodeAt(k)); } return crytxt; } </script> <script> var k = ‘app‘; var key = sha1(‘app‘); var v = ‘321‘; var yihuo = xor_enc(v,key); console.log(‘秘鑰:‘+k); console.log(‘明文:‘+v); console.log(‘sha1加密秘鑰:‘+key); console.log(‘異或運算:‘+yihuo); console.log(‘base64_encode編碼:‘+Base64.encode(yihuo)); </script>

運行效果圖:

技術分享圖片

php,js 對字符串按位異或運算加密解密