javascript - 如何将 NumPy 字符串转换为较短的版本,然后恢复为正常形式?

标签 javascript string encoding

我有一串数字,例如“1324436234235464234”。我需要将此字符串转换为“5R2f2t4”或其他符号序列,不​​是很长,所有这些都必须在客户端上实现。完成此转换后,需要将其转换回服务器端(node.js)。

它看起来像加密/解密任务,但在这种情况下我不关心安全性。是否可以实现这个转换序列?

更新:我无法使用数据库。

最佳答案

由于您的输入字符串始终具有相同的长度,因此您可以将十进制转换为其他更高的基数。

转换为缩写形式:

const encode = (alphabetString, input) => {
    const alphabet = Array.from(alphabetString);

    const digits = input.split('').map(Number);
    const result = [];

    for (;;) {
        let isZero = true;

        // Divide the number in `digits` by the alphabet size
        let carry = 0;

        for (let i = 0; i < digits.length; i++) {
            const digit = 10 * carry + digits[i];

            if (digit !== 0) {
                isZero = false;
            }

            digits[i] = digit / alphabet.length >>> 0;
            carry = digit % alphabet.length;
        }

        if (isZero) {
            break;
        }

        result.push(alphabet[carry]);
    }

    return result.reverse().join('') || alphabet[0];
};

const ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

console.log(encode(ALPHABET, '1324436234235464234'));

使用 BigInt 支持进行转换(即您使用的是 Node.js 10):

const decode = (alphabet, input) => {
    const map = new Map(
        Array.from(alphabet, Array.of)
    );

    const fromBase = BigInt(alphabet.length);
    let value = 0n;

    for (const c of input) {
        value = fromBase * value + BigInt(map.get(c));
    }

    return String(value);
};

const ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

console.log(decode(ALPHABET, '1Zpvmcf1O26').padStart(19, '0'));

没有 BigInt 支持的转换:

const decode = (alphabet, input) => {
    const map = new Map(
        Array.from(alphabet, Array.of)
    );

    const digits = Array.from(input, c => map.get(c));
    const result = [];

    for (;;) {
        let isZero = true;
        let carry = 0;

        for (let i = 0; i < digits.length; i++) {
            const digit = alphabet.length * carry + digits[i];

            if (digit !== 0) {
                isZero = false;
            }

            digits[i] = digit / 10 >>> 0;
            carry = digit % 10;
        }

        if (isZero) {
            break;
        }

        result.push(carry);
    }

    return result.reverse().join('') || '0';
};

const ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

console.log(decode(ALPHABET, '1Zpvmcf1O26').padStart(19, '0'));

对于 19 位数字的输入,使用 ASCII 数字和字母 (62) 给出的结果长度可达 11。如果您可以毫无问题地在字母表中放入更多字符,例如您试图在一条推文中容纳尽可能多的 19 位字符串以供机器读取,那么就这样做 – 每个额外的字符都会产生一些数字投入时间缩短(但返回递减)。

如果您需要与旧版浏览器兼容,请注意,仅在使用需要多个 UTF-16 代码单元的字符时才需要 const Alphabet = Array.from(alphabetString)。仅使用 ASCII,您可以删除该行并将 alphabetString 重命名为 alphabet

关于javascript - 如何将 NumPy 字符串转换为较短的版本,然后恢复为正常形式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51575069/

相关文章:

javascript - 需要有关如何在 javascript 中比较一个字符串和另一个字符串并删除其出现次数的建议吗?

javascript - 使用 jQuery 附加一个特殊字符不起作用

JavaScript 类型转换 : (true && 1) vs (true | | 1)

javascript - 如何使用 iframe 避免自定义 Web 邮件的 https 安全警告?

javascript - 使用 select2 将 php 数组转换为 javascript 数组

svg - 如何在LESS中包含UTF-8数据: URIs (for SVGs),?

java - 当文件名是泰语时,使用 enctype ="multipart/form-data"上传文件时出现奇怪的文件名

javascript - 有没有办法在用户按下 "print screen"按钮时隐藏图片?

c# - 查找第一个大写字符的索引

c++ - 在文本文件中搜索某个单词 C++