您的函数接受一个字符串,该字符串希望是一个仅使用字符的十六进制字符串[0-9a-fA-F]
。然后它创建一个数组,其中每两个十六进制字符转换为 0 到 255 之间的十进制整数。然后该函数立即丢弃该数组中的前 131 个元素。这意味着字符串的前 262 个字符对函数的输出没有影响(前 262 个字符可以是任何字符)。
然后是这一行:
var sliceEnd = charList[0] + charList[1] * 256;
sliceEnd 变为 0 到 65535 之间的数字(结果数组的最大大小)。基于输入字符串中索引 262 - 265 处的字符。(两个两位十六进制值转换为两个整数。位置 264 处的值乘以 256 并添加到位置 262 处的值)。
然后生成的数组包含使用相同方法从位置 270 到 270 + sliceEnd*2 的字符转换的整数。
MSN 是正确的,该函数不是 1 比 1,因此在数学上不可逆,但是您可以编写一个函数,给定一个 0 到 255 之间少于 65536 个整数的数组,可以为 foo 生成一个输入字符串,该字符串将返回该数组。具体来说,以下函数将做到这一点:
function bar(arr){
var sliceEnd = arr.length;
var temp = '00' + (sliceEnd & 255).toString(16);
var first = temp.substring(temp.length - 2);
temp = '00' + Math.floor(sliceEnd/256).toString(16);
var second = temp.substring(temp.length - 2);
var str = '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + first + second + '0000';
for(var i = 0; i < arr.length; i++){
temp = '00' + arr[i].toString(16);
str += temp.substring(temp.length - 2);
}
return str;
}
这为您提供了该属性foo(bar(x)) === x
(如果 x 是一个小于 65536 个介于 0 和 255 之间的整数的数组,如前所述),但不是该属性bar(foo(x)) === x
,因为正如 MSN 指出的那样,您的函数无法实现该属性。
例如。bar([17,125,12,11])
给出字符串:
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000117dcb"
如果您将其作为输入提供给您的函数foo
,您将返回原始数组:[17,125,12,11]
,但还有许多其他输入(这些 0 中的至少 268 个可以是 中的任何其他值[0-9a-fA-F]
,并且04
可以是大于 04 的任何值,这意味着 22 ^268*(255 - 4) 不同的字符串乘以更多,因为它只考虑小写或大写,但在乘以时不考虑两者255 - 4
。不管 22^268 无论如何对于一个输出来说都是一个荒谬的输入数量,那就是忽略它们是无限数量的字符串,这些字符串以上面的字符串开头,并且附加了任何其他十六进制字符串,由于 sliceEnd 变量,这将给出与 foo 相同的输出。