V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
ENIAC
V2EX  ›  程序员

使用 AND 和 OR 运算符实现的加密程序该如何解密?

  •  
  •   ENIAC · 2023-09-05 23:26:55 +08:00 · 1386 次点击
    这是一个创建于 473 天前的主题,其中的信息可能已经有所发展或是发生改变。

    AND 和 OR 运算是不是没有逆运算呀?那下面这种程序要如何写一个 decode 算法呢?是不是解密有另外的一个码表?有没有吊大的可以给一下解题思路?

    const codeTable = 'a=9-vBc3C0iDWJE4gFumGYsHoyIe7KxVLkXM6ZNqbOtdPwfQzh12jR5lS8nT_pUAr'
    
    const encode = json => {
        let result = ''
        for (let i = 0; i < json.length;) {
            const a = json.charCodeAt(i++)
            const b = json.charCodeAt(i++)
            const c = json.charCodeAt(i++)
            const d = a >> 2
            const e = ((3 & a) << 4) | (b >> 4)
            let f = ((b & 15) << 2) | (c >> 6)
            let g = c & 63
            isNaN(b) ? f = g = 64 : isNaN(c) && (g = 64)
            result = result + codeTable[d] + codeTable[e] + codeTable[f] + codeTable[g]
        }
        return result
    }
    
    const decode = cipher => {
    
    }
    
    12 条回复    2023-09-06 14:43:09 +08:00
    pagxir
        1
    pagxir  
       2023-09-05 23:42:14 +08:00
    这不就是 base64 编码么,只是把码表换而已。
    gwy15
        2
    gwy15  
       2023-09-05 23:42:25 +08:00
    这就是一个自定义了映射的 base64 编码
    momocraft
        3
    momocraft  
       2023-09-05 23:48:55 +08:00
    假定可以解密而且代码是对的,因为我不知道这里用 charCodeAt 是不是对
    注意到每次循环把 json 的 3 字符编码成 result4 个字符
    所以把 \x00\x00\x00 ~ \xff\xff\xff 跑一遍就得到码表了
    NoOneNoBody
        4
    NoOneNoBody  
       2023-09-05 23:55:15 +08:00
    首先,有个词叫“位运算”,如果不懂这个,那不知道 base64 的实现原理也就正常了
    位运算虽然在高级语言使用场合不多,但它是编程的基础之一,也是各种逻辑算式在二进制整数的体现(原理),不懂的话建议补充学习一下
    laozhoubuluo
        5
    laozhoubuluo  
       2023-09-06 00:00:51 +08:00   ❤️ 1
    找 ChatGPT 写了个解密函数,测试是通过的。

    ```
    const decode = cipher => {
    let result = ''
    for (let i = 0; i < cipher.length;) {
    const d = codeTable.indexOf(cipher[i++])
    const e = codeTable.indexOf(cipher[i++])
    const f = codeTable.indexOf(cipher[i++])
    const g = codeTable.indexOf(cipher[i++])
    const a = (d << 2) | (e >> 4)
    const b = ((e & 15) << 4) | (f >> 2)
    const c = ((f & 3) << 6) | g
    result += String.fromCharCode(a)
    if (f !== 64) {
    result += String.fromCharCode(b)
    }
    if (g !== 64) {
    result += String.fromCharCode(c)
    }
    }
    return result
    }
    ```
    ENIAC
        6
    ENIAC  
    OP
       2023-09-06 00:03:48 +08:00
    原来如此,没有想到 base64 那里去,乍一看还是挺相似的,感谢感谢!
    ENIAC
        7
    ENIAC  
    OP
       2023-09-06 00:04:41 +08:00
    @laozhoubuluo 有用过 chatgpt 写,但是我拿着密文解出来之后部分字符是乱码的
    laozhoubuluo
        8
    laozhoubuluo  
       2023-09-06 00:36:53 +08:00
    @ENIAC 仔细测试了一下发现了个问题,encode 似乎并不能处理中文。

    例如:
    ```
    const json = '{"Username":"测试","UID":20}';
    const encoded = encode(json);
    console.log("编码内容:", encoded);
    ```

    返回结果是(空格是我添加以便区分的):
    编码内容: x10Y75Y1eNBwyuCnC undefined undefined YCXzXYGZvCMb1W3jr

    那这样的话如果输入内容包含中文,那么势必会出现乱码的情况的。
    hyperbin
        9
    hyperbin  
       2023-09-06 08:23:57 +08:00 via Android
    除非你是密码学专业,否则永远不要使用自己写的加密
    sherlockwhite
        10
    sherlockwhite  
       2023-09-06 09:58:08 +08:00
    ```
    const decode = cipher => {
    let result = ''
    for(let i = 0; i < cipher.length; i+=4) {
    const a = codeTable.indexOf(cipher[i])
    const b = codeTable.indexOf(cipher[i+1])
    const c = codeTable.indexOf(cipher[i+2])
    const d = codeTable.indexOf(cipher[i+3])

    const n1 = a << 2 | b >> 4
    const n2 = (b & 15) << 4 | c >> 2
    const n3 = (c & 3) << 6 | d
    result += String.fromCharCode(n1)
    if(c != 64) {
    result += String.fromCharCode(n2)
    }
    if(d != 64) {
    result += String.fromCharCode(n3)
    }
    }
    return result
    }
    ```
    zbinlin
        11
    zbinlin  
       2023-09-06 10:19:55 +08:00
    @laozhoubuluo 这肯定要先转成 utf8 字节再 encode 才行
    mcfog
        12
    mcfog  
       2023-09-06 14:43:09 +08:00
    b64Table='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
    decode = s=>atob(Array.from(s).map(c=>b64Table[codeTable.indexOf(c)]).join(''))
    console.log(decode(encode('Hello World!')))

    没啥毛病,中文是因为整个过程用 charcode 当取字节用了,但实际上 charcode 取的是 unicode codepoint
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2913 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 13:50 · PVG 21:50 · LAX 05:50 · JFK 08:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.