Base64转换小数

时间:2017-03-09 17:35:45

标签: python encoding character-encoding language-agnostic base64

我一直在阅读有关base64转换的内容,据我所知,原始数据的编码版本将是原始大小的133%。

然后,我正在阅读有关YouTube如何为其FJZQSHn7fc等视频提供唯一标识符的原因是:11个字符的base64字符串可以映射到一个巨大的数字。

等等,假设一个巨大的数字包含20个字符,那么base64编码的字符串不会是该字号的133%,而不是更短吗?

我很困惑。是否有不同类型的base64转换(字符串到base64对十进制到base64),一次导致更大,另一种导致更小的结果字符串?

4 个答案:

答案 0 :(得分:1)

基数64中的每个字符可以编码6位数据。因此,11个字符可以编码6x11 = 66位数据。

2^66 = 73786976294838206464

73786976294838206464(约7.4 x 10 ^ 19或74 quintillion)可能的标识符足以在可预见的未来区分独特的YouTube视频。

YouTube不太可能使用长度为11的字符串作为较小对象的编码。您可以使用base64(毕竟只是基数64中的数字)而不必将其视为其他内容的编码,就像您可以使用字节(8位的二进制数)而不将这些字节视为ascii的编码字符。标识符方案唯一重要的问题是,是否有足够的标识符可供使用。在这种情况下,显然有。

答案 1 :(得分:1)

可以这样想:你有一个64位的数字(例如,在Java中称为 long )。

现在,您可以用不同的方式打印该号码:

  • 作为二进制数(基数2),打印64'0'或'1'
  • 作为十进制数字(基数为10),最多打印20位小数
  • 作为十六进制数字(基数为16),打印16个十六进制数字
  • 作为基数为64的数字,在该基数中打印11个“数字”。您可以将任何图形符号用作数字。
  • ...你现在明白还有更多的可能性......

它们似乎使用与base64编码中使用的相同的base-64数字,即大写和小写字母,普通数字和2个额外字符。每个字符代表一个6位值。因此,您获得66位,并且根据所使用的算法,前导或后2位被切断以获得良好的值。

答案 2 :(得分:0)

你对比较的东西感到困惑。 有两个陈述,都比较了不同的东西:

  1. " base64编码比原始大小"
  2. 大133%
  3. " 11个字符的base64字符串可以编码一个巨大的数字"
  4. 1 的情况下,它们通常是指使用8位字符编码的字符串,并将其与base64中编码的相同字符串进行比较。这比133%大,因为在base64中你不能在每个字节中使用所有255位组合。

    2 的情况下,他们使用数字标识符进行比较,然后将其编码为base64或base10。在这种情况下,base64比base10短很多。

    您还可以将(1)情况视为将base256与base64进行比较,将(2)情况视为将base10与base64进行比较。

答案 3 :(得分:0)

当您说Base64时,有些人会想到RFC 4648。如果YouTube使用的是RFC 4648,则它是一个12位数字,因此他们省略了最后一位数字,因为它始终是'=',即填充字符(base64字母的第65个元素)。 12个数字代表三个数字块,四个数字产生24位信息。因此,如果YouTube视频ID使用的是标准视频,则它将是64位而非66位。

那些64位可能表示一个无符号整数。 YouTube使用MySQL,然后通过Vitess分片MySQL,因此您可以想象它们在内部使用UNSIGNED BIGINT密钥,并在外部通过兼容RFC 4648的Base64进行编码。

很明显,汤姆·斯科特(Tom Scott)认为YouTube从其11个字符中挤出了66位;他的video这样说。

如果他错了,那么他们的前端可能使您可以为同一视频指定四个不同的视频ID。这两个额外位的值不会影响UNSIGNED BIGINT。它们是哪两位取决于字节顺序和其他编码选择。

无论YouTube使用的是标准编码还是非标准编码,它们都可以用11个字符表示18446744073709551615(因为填充字符始终存在,因此对于64位数字将被省略)。

也许在创建新视频时,他们使用以下类似方法来计算伪随机的64位整数:

import base64
import random

def Base64RandomSlug():
  array = bytearray(random.getrandbits(8) for x in range(64 // 8))
  b = base64.urlsafe_b64encode(bytes(array))
  return b.decode('utf-8').rstrip('=')