第一件事:必须完全用javascript完成。 (JQuery / mootools可选)
我有一系列100个数字,每个数字设置为0,1,2或3 - 这些代表页面上的设置。我想将这些编码为最短的字符串,以创建页面的永久链接。
我认为最好的方法是将它们存储在二进制对联中,将这些对偶转换为字符串,然后对该字符串进行urlencode。
然而,到目前为止我发现的最好的是parseint( binary_var, 2 )
,它将二进制数转换为base_10数。但是为了让字符串足够短,我需要一个更好的系统。
如果我可以转换为64位编码,我认为我可以将所有数据存储在4个字符中。我知道网址现在支持unicode,我相信我可以使用escape
和unescape
来编码/解码64位字符,所以我要找的主要方法是编码/解码二进制数据到64位字符。
当然,我不是百分百肯定这是最好的方式,或者甚至会工作,所以我完全偏离轨道随意指出我正确的方向。
谢谢!
答案 0 :(得分:1)
你可以将这样的数字数组编码成一个字符串,每个字符3个,如下所示:
function encodeBase4(base4) {
var i, rv = [], n = ~~((base4.length + 2) / 3) * 3;
for (i = 0; i < n; i += 3) {
rv.push(
32 +
((base4[i] || 0) & 3) +
((base4[i + 1] || 0) & 3) * 4 +
((base4[i + 2] || 0) & 3) * 16
);
}
return String.fromCharCode.apply(null, rv);
}
然后你可以像这样转换另一个方向:
function decodeBase4(str) {
var i, rv = [], n = str.length;
for (i = 0; i < n; ++i) {
var b = str.charCodeAt(i) - 32;
rv.push(b & 3);
rv.push(~~(b / 4) & 3);
rv.push(~~(b / 16) & 3);
}
return rv;
}
这里的the jsfiddle似乎适用于其简单的测试用例。 (请注意,您最终会得到一个长度为3的倍数的列表;您必须知道有多少实数值,并且最后忽略零。)
现在这些结果字符串将“脏”并且如果您将它们放入URL中则需要URL编码。如果每个字符只打包2个数字,则可以使得结果字符串全部为字母,从而避免编码惩罚;但是,当然,它们会更长。
答案 1 :(得分:0)
每条2比特的100条信息总共需要200比特。使用base 64编码,你需要ceil(200 / log 2 (64))= 34个字符。
URI path segment允许79个字符不需要使用百分比编码进行编码。如果添加路径段分隔符/
,则有80个字符,因此需要ceil(200 / log 2 (80))= 32个字符。这是单独使用路径可以达到的最佳效果。
您可以使用多个字符,甚至是Unicode字符。但是那些需要使用百分比编码进行编码,因为URI只允许包含US-ASCII。像/ä
(ä
= U + 00E4)这样的URI路径实际上是/%C3%A4
,只有浏览器会将其显示为/ä
。
以下是一个示例(从arbitrary base conversion in javascript获取的函数):
function getValueOfDigit(digit, alphabet)
{
var pos = alphabet.indexOf(digit);
return pos;
}
function convert(src, srcAlphabet, dstAlphabet)
{
var srcBase = srcAlphabet.length;
var dstBase = dstAlphabet.length;
var wet = src;
var val = 0;
var mlt = 1;
while (wet.length > 0)
{
var digit = wet.charAt(wet.length - 1);
val += mlt * getValueOfDigit(digit, srcAlphabet);
wet = wet.substring(0, wet.length - 1);
mlt *= srcBase;
}
wet = val;
var ret = "";
while (wet >= dstBase)
{
var digitVal = wet % dstBase;
var digit = dstAlphabet.charAt(digitVal);
ret = digit + ret;
wet /= dstBase;
}
var digit = dstAlphabet.charAt(wet);
ret = digit + ret;
return ret;
}
var base4Alphabet = "0123",
base79Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&'()*+,;=:@",
base80Alphabet = base79Alphabet+"/";
alert(convert(getValueOfDigit("010203210", base4Alphabet), base4Alphabet, base80Alphabet)); // "C@Q"