【问题标题】:Writing a function in javascript that is the inverse of another用javascript编写一个与另一个相反的函数
【发布时间】:2012-01-07 05:50:35
【问题描述】:

我正在尝试编写一个与下面的函数相反的函数。

这样我就可以从函数 foo 中获取输出并生成它的输入参数。

我不完全确定这是否可能。

function foo(str){
    var hexMap = {
        "0":0,
        "1":1,
        "2":2,
        "3":3,
        "4":4,
        "5":5,
        "6":6,
        "7":7,
        "8":8,
        "9":9,
        "A":10,
        "B":11,
        "C":12,
        "D":13,
        "E":14,
        "F":15
    };
    var charList = [];

    str = str.toUpperCase();               


    for (var i = 0; i < str.length; i += 2) {
        charList.push(hexMap[str.charAt(i)] * 16 + hexMap[str.charAt(i + 1)]);
    }

    charList.splice(0, 8);
    charList.splice(0, 123);

    var sliceEnd = charList[0] + charList[1] * 256;
    charList.splice(0, 4);

    charList = charList.slice(0, sliceEnd); 
    return charList;
}

【问题讨论】:

  • 用通俗易懂的英语解释一下,您想要实现什么,而不是向我们抛出代码转储并期望我们理解它。

标签: javascript algorithm hex inverse reversing


【解决方案1】:

您的函数接收一个字符串,该字符串希望是一个仅使用字符[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 指出的那样,该属性是不可能实现的为您的功能。

EG。 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 的输出相同。

【讨论】:

  • +1 表示努力实际找到右逆(并且因为它是一个很好的答案)。
【解决方案2】:

该函数不是一对一的函数,即许多输入将产生相同的输出。

【讨论】:

  • 证明:你在调用charList.splice时丢弃了部分输入字符串。
  • 他可以扔掉部分字符串,但只有在有删除部分的模式时才能恢复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-27
  • 1970-01-01
  • 1970-01-01
  • 2013-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多