在 javascript 中反向按位移位
bitwise shifting in reverse in javascript
我想知道如何使以下位移过程反向进行?
chr1 = (enc1 | ((enc2 & 3) << 6));
chr2 = (enc2 >> 2) | ((enc3 & 0x0F) << 4);
chr3 = (enc3 >> 4) | (enc4 << 2);
这基本上是为我正在使用的解码脚本移动位。我想知道有没有办法逆转这个过程,编码而不是解码?
这来自以下以 base64 解码的脚本:
Base64 = {
_keyStr: ".ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+=",
decode: function( input ) {
var output = "";
var hex = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;
var base64test = /[^A-Za-z0-9\+\.\=]/g;
do {
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 | ((enc2 & 3) << 6));
chr2 = (enc2 >> 2) | ((enc3 & 0x0F) << 4);
chr3 = (enc3 >> 4) | (enc4 << 2);
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return (output);
}
}
观察以下计算:
// enc = [0, 1, 0, 0]
chr1 = (0 | ((1 & 3) << 6)) = 64
chr2 = (1 >> 2) | ((0 & 0x0F) << 4) = 0
chr3 = (0 >> 4) | (0 << 2) = 0
// enc = [64, 0, 0, 0]
chr1 = (64 | ((0 & 3) << 6)) = 64
chr2 = (0 >> 2) | ((0 & 0x0F) << 4) = 0
chr3 = (0 >> 4) | (0 << 2) = 0
由于两个输入映射到相同的输出,该函数不是injective,即不能反转。
如果您假设 enc 的所有值都小于 64,您可以反转它:
enc1 = chr1 & 0x3f;
enc2 = (chr1 >> 6) | ((chr2 & 0xf) << 2);
enc3 = (chr2 >> 4) | ((chr3 & 0x3) << 4);
enc4 = chr3 >> 2;
由于 space 的值不是那么大,您可以简单地全部测试它们,就在您的浏览器中:
'use strict';
function _indicate(status) {
var indicator = document.querySelector('.indicator');
while (indicator.firstChild) {
indicator.removeNode(firstChild);
}
indicator.setAttribute('class', status);
indicator.appendChild(document.createTextNode(status));
}
function test(enc1, enc2, enc3, enc4) {
var chr1 = (enc1 | ((enc2 & 3) << 6));
var chr2 = (enc2 >> 2) | ((enc3 & 0x0F) << 4);
var chr3 = (enc3 >> 4) | (enc4 << 2);
var dec1 = chr1 & 0x3f;
var dec2 = (chr1 >> 6) | ((chr2 & 0xf) << 2);
var dec3 = (chr2 >> 4) | ((chr3 & 0x3) << 4);
var dec4 = chr3 >> 2;
if ((enc1 !== dec1) || (enc2 !== dec2) || (enc3 !== dec3) || (enc4 !== dec4)) {
console.log('FAIL');
console.log('chr ' + chr1 + ', ' + chr2 + ', ' + chr3);
console.log('Expected/got: ' + enc1 + '/' + dec1 + ', ' + enc2 + '/' + dec2 + ', ' + enc3 + '/' + dec3 + ', ' + enc4 + '/' + dec4);
_indicate('fail');
throw new Error('Failed test');
}
}
for (var enc1 = 0; enc1 < 63; enc1++) {
for (var enc2 = 0; enc2 < 63; enc2++) {
for (var enc3 = 0; enc3 < 63; enc3++) {
for (var enc4 = 0; enc4 < 63; enc4++) {
test(enc1, enc2, enc3, enc4);
}
}
}
}
_indicate('pass');
.fail {
background: red;
}
.pass {
background: green;
}
<div class="indicator"></div>
我想知道如何使以下位移过程反向进行?
chr1 = (enc1 | ((enc2 & 3) << 6));
chr2 = (enc2 >> 2) | ((enc3 & 0x0F) << 4);
chr3 = (enc3 >> 4) | (enc4 << 2);
这基本上是为我正在使用的解码脚本移动位。我想知道有没有办法逆转这个过程,编码而不是解码?
这来自以下以 base64 解码的脚本:
Base64 = {
_keyStr: ".ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+=",
decode: function( input ) {
var output = "";
var hex = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;
var base64test = /[^A-Za-z0-9\+\.\=]/g;
do {
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 | ((enc2 & 3) << 6));
chr2 = (enc2 >> 2) | ((enc3 & 0x0F) << 4);
chr3 = (enc3 >> 4) | (enc4 << 2);
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return (output);
}
}
观察以下计算:
// enc = [0, 1, 0, 0]
chr1 = (0 | ((1 & 3) << 6)) = 64
chr2 = (1 >> 2) | ((0 & 0x0F) << 4) = 0
chr3 = (0 >> 4) | (0 << 2) = 0
// enc = [64, 0, 0, 0]
chr1 = (64 | ((0 & 3) << 6)) = 64
chr2 = (0 >> 2) | ((0 & 0x0F) << 4) = 0
chr3 = (0 >> 4) | (0 << 2) = 0
由于两个输入映射到相同的输出,该函数不是injective,即不能反转。
如果您假设 enc 的所有值都小于 64,您可以反转它:
enc1 = chr1 & 0x3f;
enc2 = (chr1 >> 6) | ((chr2 & 0xf) << 2);
enc3 = (chr2 >> 4) | ((chr3 & 0x3) << 4);
enc4 = chr3 >> 2;
由于 space 的值不是那么大,您可以简单地全部测试它们,就在您的浏览器中:
'use strict';
function _indicate(status) {
var indicator = document.querySelector('.indicator');
while (indicator.firstChild) {
indicator.removeNode(firstChild);
}
indicator.setAttribute('class', status);
indicator.appendChild(document.createTextNode(status));
}
function test(enc1, enc2, enc3, enc4) {
var chr1 = (enc1 | ((enc2 & 3) << 6));
var chr2 = (enc2 >> 2) | ((enc3 & 0x0F) << 4);
var chr3 = (enc3 >> 4) | (enc4 << 2);
var dec1 = chr1 & 0x3f;
var dec2 = (chr1 >> 6) | ((chr2 & 0xf) << 2);
var dec3 = (chr2 >> 4) | ((chr3 & 0x3) << 4);
var dec4 = chr3 >> 2;
if ((enc1 !== dec1) || (enc2 !== dec2) || (enc3 !== dec3) || (enc4 !== dec4)) {
console.log('FAIL');
console.log('chr ' + chr1 + ', ' + chr2 + ', ' + chr3);
console.log('Expected/got: ' + enc1 + '/' + dec1 + ', ' + enc2 + '/' + dec2 + ', ' + enc3 + '/' + dec3 + ', ' + enc4 + '/' + dec4);
_indicate('fail');
throw new Error('Failed test');
}
}
for (var enc1 = 0; enc1 < 63; enc1++) {
for (var enc2 = 0; enc2 < 63; enc2++) {
for (var enc3 = 0; enc3 < 63; enc3++) {
for (var enc4 = 0; enc4 < 63; enc4++) {
test(enc1, enc2, enc3, enc4);
}
}
}
}
_indicate('pass');
.fail {
background: red;
}
.pass {
background: green;
}
<div class="indicator"></div>