关于javascript:使用Crockford的基础32来获取URL中的ID?

Using Crockford's base 32 for IDs in URLs?

我想写一些ID用于Crockford的base32中的URL。我正在使用base32 NPM模块。

例如,如果用户键入http://domain/page/4a2a,我希望它映射到与http://domain/page/4a2a相同的基础ID

这是因为我想要人性化的URL,用户不必担心大小写字母之间的区别,或者"l"和"1"之间的区别,他们只需要得到他们想要的页面。

但我正在努力实现这一点,基本上是因为我太迟钝,无法理解编码是如何工作的。首先我试过:

1
2
3
var encoded1 = base32.encode('4a2a');
var encoded2 = base32.encode('4A2A');
console.log(encoded1, encoded2);

但它们映射到不同的底层ID:

1
6hgk4r8 6h0k4g8

好吧,也许我需要使用解码?

1
2
3
var encoded1 = base32.decode('4a2a');
var encoded2 = base32.decode('4A2A');
console.log(encoded1, encoded2);

不,那只会给我空字符串:

1
"   "

我做错了什么?如何让4A2A和4A2A映射到同一个东西?


对于一个传入的请求,您需要对URL片段进行解码。创建URL时,将获取标识符并对其进行编码。因此,给定一个URL http://domain/page/dnwnyub46m50,您将获取该片段并对其进行解码。例子:

#> echo 'dnwnyub46m50'| base32 -d

my_id5

链接到的库不区分大小写,因此您可以通过以下方式获得相同的结果:

echo 'DNWNYUB46M50'| base32 -d

my_id5

在处理任何编码方案(base-16/32/64)时,您有两个基本操作:在位/字节的原始流上工作的encode和接收一组已编码字节并返回原始位/字节流的decode。base32编码上的维基百科页面是一个很好的资源。

解码字符串时,会得到原始字节:可能是这些字节与ASCIIUTF-8或您尝试使用的其他编码不兼容。这就是为什么解码后的示例看起来像空格:您使用的工具无法将结果字节识别为有效字符。

如何对标识符进行编码取决于如何生成标识符。您没有说您是如何生成底层标识符的,所以我不能对应该如何处理解码器输出的原始字节,以及将原始字节的内容传递给编码器做出任何假设。

同样重要的一点是,您链接到的库与Crockford的base32编码不兼容。库中不包括I, L, O, S,而crockford的编码则不包括I, L, O, U。如果您试图与另一个使用不同库的系统进行互操作,这将是一个问题。如果除了你之外没有人需要解码你的URL片段,那么互操作性就不重要了。


拥有JavaScript

ParseInt(数字,32)

数字ToString(32)

以Java和JavaScript版本兼容的方式构建。


您困惑的根源在于base64或base32是表示数字的方法,而您在示例中试图对文本字符串进行编码或解码。

将文本字符串作为base32进行编码和解码时,首先要将该字符串转换为一个大数字。在您的第一个示例中,您正在对"4A2A"和"4A2A"进行编码,它们是具有两个不同数值的字符串,因此转换为具有两个不同值的编码base32数字6hgk4r8 6h0k4g8

当你"解码"4A2A和4A2A时,你说你得到了空字符串。但是,这不是真的,字符串不是空的,它们包含解码后的数字在解释为字符串时的样子。也就是说,4A2A产生了一个不可打印的字符,所以看起来什么都不像。它是隐形的。你想要的是输入编码器的数字,而不是字符串。