我一直在阅读有关base64转换的内容,据我所知,原始数据的编码版本将是原始大小的133%。
然后,我正在阅读有关YouTube如何为其FJZQSHn7fc
等视频提供唯一标识符的原因是:11个字符的base64字符串可以映射到一个巨大的数字。
等等,假设一个巨大的数字包含20个字符,那么base64编码的字符串不会是该字号的133%,而不是更短吗?
我很困惑。是否有不同类型的base64转换(字符串到base64对十进制到base64),一次导致更大,另一种导致更小的结果字符串?
答案 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 )。
现在,您可以用不同的方式打印该号码:
它们似乎使用与base64编码中使用的相同的base-64数字,即大写和小写字母,普通数字和2个额外字符。每个字符代表一个6位值。因此,您获得66位,并且根据所使用的算法,前导或后2位被切断以获得良好的长值。
答案 2 :(得分:0)
你对比较的东西感到困惑。 有两个陈述,都比较了不同的东西:
在 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('=')