为什么将分页游标或id值编码为字符串是一种常见做法?

时间:2015-02-08 02:24:03

标签: facebook-graph-api cursor base64

例如Facebook Graph API:为什么afterbefore base64编码的数字?

{
  "data": [
     ... Endpoint data is here
  ],
  "paging": {
    "cursors": {
      "after": "MTAxNTExOTQ1MjAwNzI5NDE=",
      "before": "NDMyNzQyODI3OTQw"
    },
    "previous": "https://graph.facebook.com/me/albums?limit=25&before=NDMyNzQyODI3OTQw"
    "next": "https://graph.facebook.com/me/albums?limit=25&after=MTAxNTExOTQ1MjAwNzI5NDE="
  }
}

与普通数字相比,它可能带来什么好处?

如下面的python日志所示,优点不能是数据的简短表示或包含不安全字符的数据:

>>> base64.b64decode("MTAxNTExOTQ1MjAwNzI5NDE=")
'10151194520072941'
>>> len('10151194520072941')
17
>>> len("MTAxNTExOTQ1MjAwNzI5NDE=")
24

2 个答案:

答案 0 :(得分:3)

<击>  如果你的意思是使用基数10(十进制),当你说普通数字时,那么优点是基数64更紧凑,使用更少的数字(10位数的基数10数字(例如1,000,000,000)可以用基数64中的5位数表示(例如F9eEA)),以及(如你所说)隐藏实现细节。

如果您的意思是在使用简单数字时使用原始二进制数据,则base 64使用几乎总是安全的字符通过互联网,URL等传输而不会将某些字符解释为控制字符(这是一种风险)当传输原始二进制数据时)。有关详细信息,请参阅this other question

在任何一种情况下,使用base64都有优势。

修改

我明白你的意思,之前列出的优点不适用于这种情况。 Facebook可能使用base64与其他API函数保持一致,以及隐藏实现细节。如果他们将来修改它以允许其他字符,以及容忍潜在的格式错误请求(假设错误发生在base64转换之前),也可能是有利的。

答案 1 :(得分:3)

根据StackOverflow What is JavaScript's highest integer value that a Number can go to without losing precision?中提出的问题,JavaScript中最高的数字是9007199254740992

如果比较这些值

9007199254740992    // the JS maximum
10151194520072941   // the Base64 encoded number

如果看起来Facebook内部存在 - 出于我们不知道的原因 - 存储的值太大而无法处理JavaScript数字精度。

因此,在我看来,除了将数字作为字符串处理之外,他们没有其他可能性。

当然,他们可以使用"10151194520072941"作为字符串格式的数字,但是一些程序员可能会将此混淆为数字。尽管很少发生这种情况,但他们可能认为Base64编码的数字避免了将某个字符串转换为整数的问题。

此外,因为这是公共API函数,所以它们不被自己的工程师使用,因此风险更高,因为使用API​​的人来自不同的教育背景。他们可能会意外地使用例如parseInt或类似于导致不必要的客户服务请求的数字。

编辑:使用非常大的数字可能还有另一个目的:检测有目的滥用API。如果他们将使用例如随机UUID值或连续数值,则任何附近值都可能是合法的。如果是UUID,他们首先必须提出请求以查看它是否是合法条目。拥有大量基数可能只有每1000个是合法的,或者它们遵循一些其他数学规则,可以由单个服务器检测到,而无需向其他服务器请求,整理出有目的地制作具有非法值的请求的客户端变得更多有效的,也许可以在它们到达数据库之前被过滤掉。