将 170 位二进制字符串转换为更短的格式并再次返回 (Javascript)
Convert 170 Digit Binary String Into Shorter Format and Back Again (Javascript)
我做了一个小拼图模拟here。
170 个单元格的 on/off 状态(有些对用户不可见)存储在一个数组中,为了能够重新创建特定配置,我将数组的内容显示在页面,然后可以将其作为 URL 参数放入 "set up" 页面加载时的特定配置 like so.
我的问题是数组的输出是一个170位的二进制数,比较麻烦!
我尝试使用
parseInt(input,2).toString(30)
和
parseInt(input,30).toString(2)
作为一种简单地将这个 170 位二进制数转换为更小的字母数字格式的方法(然后再次返回以供我的 "set up" 初始化程序读取)但据我所知,我的数字是处理太大,不适合那种功能。
我的下一个想法是,我可以将 170 位数字分成几个部分,这些部分可以被函数消化,但是当我确定这种转换必须是很常见,有人可以直接告诉我 "right" 的方法。
提前致谢!
你的想法是正确的,只是JavaScript不能准确表示那么大的数字。当您使用 parseInt
将其转换为 JavaScript 数字时,您的 170 位数字将失去准确性;不代表原数是逐位的。
解决方案很简单:滚动您自己的数字解析函数,以较小的块处理 170 位数字。
function encode(a) {
var b = "";
while (a.length > 0) {
b = parseInt(a.slice(-5), 2).toString(32) + b;
a = a.slice(0, -5);
}
return b;
}
function decode(a) {
var b = "";
while (a.length > 0) {
b = ("00000" + parseInt(a.slice(-1), 32).toString(2)).slice(-5) + b;
a = a.slice(0, -1);
}
return b;
}
var s = "00000000000000010101110100001010100010000111011101000010101000100001010111011100000000000000010001110010001000101001000100010100100010001010000001110111001000000000000000";
var e = encode(s); // "000lq2k8et1a45es002748kh2i4a0tp000"
var d = decode(e); // d === s
更通用的函数:
function convert(string, base1, base2) {
var result = "",
chunkw = 0, // number of characters to write per chunk
chunkr = 0, // number of characters to read per chunk
padstr = "", // string of zeros for padding the write chunks
slice;
while (Math.pow(2, chunkw) < base1) chunkw += 1;
while (Math.pow(2, chunkr) < base2) chunkr += 1;
while (padstr.length < chunkw) padstr += "0";
while (string.length > 0) {
slice = string.slice(-chunkr);
slice = parseInt(slice, base1).toString(base2);
slice = (padstr + slice).slice(-chunkw);
result = slice + result;
string = string.slice(0, -chunkr);
}
return result;
}
var x = "00000000000000010101110100001010100010000111011101000010101000100001010111011100000000000000010001110010001000101001000100010100100010001010000001110111001000000000000000";
var a = convert(x, 2, 32);
var b = convert(a, 32, 2);
console.log(x + "\n" + a + "\n" + b);
// 00000000000000010101110100001010100010000111011101000010101000100001010111011100000000000000010001110010001000101001000100010100100010001010000001110111001000000000000000
// 000lq2k8et1a45es002748kh2i4a0tp000
// 00000000000000010101110100001010100010000111011101000010101000100001010111011100000000000000010001110010001000101001000100010100100010001010000001110111001000000000000000
我做了一个小拼图模拟here。
170 个单元格的 on/off 状态(有些对用户不可见)存储在一个数组中,为了能够重新创建特定配置,我将数组的内容显示在页面,然后可以将其作为 URL 参数放入 "set up" 页面加载时的特定配置 like so.
我的问题是数组的输出是一个170位的二进制数,比较麻烦!
我尝试使用
parseInt(input,2).toString(30)
和
parseInt(input,30).toString(2)
作为一种简单地将这个 170 位二进制数转换为更小的字母数字格式的方法(然后再次返回以供我的 "set up" 初始化程序读取)但据我所知,我的数字是处理太大,不适合那种功能。
我的下一个想法是,我可以将 170 位数字分成几个部分,这些部分可以被函数消化,但是当我确定这种转换必须是很常见,有人可以直接告诉我 "right" 的方法。
提前致谢!
你的想法是正确的,只是JavaScript不能准确表示那么大的数字。当您使用 parseInt
将其转换为 JavaScript 数字时,您的 170 位数字将失去准确性;不代表原数是逐位的。
解决方案很简单:滚动您自己的数字解析函数,以较小的块处理 170 位数字。
function encode(a) {
var b = "";
while (a.length > 0) {
b = parseInt(a.slice(-5), 2).toString(32) + b;
a = a.slice(0, -5);
}
return b;
}
function decode(a) {
var b = "";
while (a.length > 0) {
b = ("00000" + parseInt(a.slice(-1), 32).toString(2)).slice(-5) + b;
a = a.slice(0, -1);
}
return b;
}
var s = "00000000000000010101110100001010100010000111011101000010101000100001010111011100000000000000010001110010001000101001000100010100100010001010000001110111001000000000000000";
var e = encode(s); // "000lq2k8et1a45es002748kh2i4a0tp000"
var d = decode(e); // d === s
更通用的函数:
function convert(string, base1, base2) {
var result = "",
chunkw = 0, // number of characters to write per chunk
chunkr = 0, // number of characters to read per chunk
padstr = "", // string of zeros for padding the write chunks
slice;
while (Math.pow(2, chunkw) < base1) chunkw += 1;
while (Math.pow(2, chunkr) < base2) chunkr += 1;
while (padstr.length < chunkw) padstr += "0";
while (string.length > 0) {
slice = string.slice(-chunkr);
slice = parseInt(slice, base1).toString(base2);
slice = (padstr + slice).slice(-chunkw);
result = slice + result;
string = string.slice(0, -chunkr);
}
return result;
}
var x = "00000000000000010101110100001010100010000111011101000010101000100001010111011100000000000000010001110010001000101001000100010100100010001010000001110111001000000000000000";
var a = convert(x, 2, 32);
var b = convert(a, 32, 2);
console.log(x + "\n" + a + "\n" + b);
// 00000000000000010101110100001010100010000111011101000010101000100001010111011100000000000000010001110010001000101001000100010100100010001010000001110111001000000000000000
// 000lq2k8et1a45es002748kh2i4a0tp000
// 00000000000000010101110100001010100010000111011101000010101000100001010111011100000000000000010001110010001000101001000100010100100010001010000001110111001000000000000000