You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将ROBLOX Lua轻量加密代码及('%02x'):format写法转换为Node.js实现

Roblox Lua轻量加密算法Node.js迁移方案

核心问题解决

你调试失败的核心语法("%02x"):format(c)是Lua中将0-255整数转为两位小写十六进制字符串的内置方法,Node.js中等效实现为:

(c & 0xff).toString(16).padStart(2, '0')

额外加& 0xff是为了兼容JavaScript取模运算可能返回负数的特性,保证输入数值始终落在0-255的合法区间,和Lua端输出结果完全一致。

注意事项

  • Lua默认支持大整数运算,Node.js中普通Number类型超过2^53会丢失精度,因此所有涉及密钥K的运算需要用BigInt类型实现,否则加密/解密结果会和Lua端不匹配
  • inv256预生成逻辑和Lua端完全一致,可提前生成缓存避免重复计算

原Lua完整实现代码

local Key53 = 8186484168865098
local Key14 = 4887
local inv256

function encode(str)
    if not inv256 then
        inv256 = {}
        for M = 0, 127 do
            local inv = -1
            repeat 
                inv = inv + 2
            until inv * (2*M + 1) % 256 == 1
            inv256[M] = inv
        end
    end

    local K, F = Key53, 16384 + Key14
    return (str:gsub('.',
        function(m)
            local L = K % 274877906944  -- 2^38
            local H = (K - L) / 274877906944
            local M = H % 128
            m = m:byte()

            local c = (m * inv256[M] - (H - M) / 128) % 256
            K = L * F + H + c + m
            
            return ('%02x'):format(c)
        end
    ))
end

function decode(str)
    local K, F = Key53, 16384 + Key14
    return (str:gsub('%x%x',
        function(c)
            local L = K % 274877906944  -- 2^38
            local H = (K - L) / 274877906944
            local M = H % 128
            c = tonumber(c, 16)

            local m = (c + (H - M) / 128) * (2*M + 1) % 256
            K = L * F + H + c + m

            return string.char(m)
        end
    ))
end

等效Node.js完整实现代码

const Key53 = 8186484168865098n;
const Key14 = 4887n;
const F = 16384n + Key14;
const POW_2_38 = 274877906944n;

// 预生成inv256表,和Lua逻辑完全一致
const inv256 = new Array(128);
for (let M = 0; M < 128; M++) {
  let inv = -1;
  do {
    inv += 2;
  } while ((inv * (2 * M + 1)) % 256 !== 1);
  inv256[M] = inv;
}

/**
 * 加密方法,和原Lua encode输出完全一致
 * @param {string} str 待加密的明文字符串
 * @returns {string} 十六进制密文字符串
 */
function encode(str) {
  let K = Key53;
  let result = '';
  for (let i = 0; i < str.length; i++) {
    const m = str.charCodeAt(i);
    const L = K % POW_2_38;
    const H = (K - L) / POW_2_38;
    const M = Number(H % 128n);
    
    const c = (m * inv256[M] - Number((H - BigInt(M)) / 128n)) % 256;
    // 核心转换逻辑,等效Lua的("%02x"):format(c)
    const cHex = (c & 0xff).toString(16).padStart(2, '0');
    result += cHex;
    
    K = L * F + H + BigInt(c & 0xff) + BigInt(m);
  }
  return result;
}

/**
 * 解密方法,和原Lua decode输出完全一致
 * @param {string} str 十六进制密文字符串
 * @returns {string} 明文字符串
 */
function decode(str) {
  let K = Key53;
  let result = '';
  for (let i = 0; i < str.length; i += 2) {
    const cHex = str.slice(i, i + 2);
    const c = parseInt(cHex, 16);
    const L = K % POW_2_38;
    const H = (K - L) / POW_2_38;
    const M = Number(H % 128n);
    
    const m = ((c + Number((H - BigInt(M)) / 128n)) * (2 * M + 1)) % 256;
    result += String.fromCharCode(m & 0xff);
    
    K = L * F + H + BigInt(c) + BigInt(m & 0xff);
  }
  return result;
}

内容的提问来源于stack exchange,提问作者Perhaps Maybe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 13:36:03