YouTube视频ID的格式


32

每个YouTube视频都有一个唯一的ID,可用于获取该ID。例如,位于的视频http://www.youtube.com/watch?v=aN46pEO_jX8的ID为aN46pEO_jX8

经过观察,在我看来这些ID遵循以下两个规则:

  • 恰好11个字符
  • 允许的符号:az,AZ,0-9,-和_

我想知道:

  1. 这两个规则是否总是正确的。
  2. 还有其他重要的规则要遵循。

Answers:


38

根据Youtube 2.0 API文档3.0 API文档videoId是一个字符串,关于当前使用的字符集未指定任何内容。

大约11个字符的长度,Youtube API小组的一则帖子说:

我没有在文档中看到任何地方正式承诺将11个字符的标准长度用于YouTube视频ID。这是我们当前实施的事情之一,并且可能会无限期地保持下去。但是我们没有为此提供任何官方承诺,因此风险自负。

最后但并非最不重要的一点是,另一篇文章阐明了(或没有)格式:

对于视频ID的格式,我们不做任何公开保证。尽管它们当前是包含字母,数字和标点符号的11个字符串,但我不建议您将其硬编码到您的应用程序中(除非您将来有一种简单的方法来对其进行更改)。

Youtube团队似乎更喜欢直接询问Youtube服务器Video_ID是否正确(请参阅现有视频):

如果您需要验证随机用户输入是否与有效的视频ID相对应,建议您进行经验测试。尝试访问

http://gdata.youtube.com/feeds/api/videos/VIDEO_ID

如果收到200响应,则VIDEO_ID有效。如果收到非200的响应,则您的ID无效。对于新上传的视频或私人视频,有些边缘情况,但是对于大多数目的,我认为这是可以的。


这是一个很好的答案,并给了我所有我需要的信息!谢谢!
asfallows 2014年

3
这将返回一个HTTP 410。关于现在应对此进行验证的新URL有什么想法?
威尔·斯特罗尔

1
要验证视频ID:只需从youtube获取html页面,并验证元规范链接具有您指定的相同ID。
puchu

50

YouTube videoIdchannelId标识符是单个整数值,以对Base64编码稍加修改的版本表示。与IETF RFC4648建议的不同之在于,在编码字母中替换了两个字符:

 Payload  ASCII/Unicode      Base64     YouTube
 -------  -------------     ---------  ---------
  0...25  \x41 ... \x5A     'A'...'Z'  'A'...'Z'
 26...51  \x61 ... \x7A     'a'...'z'  'a'...'z'
 52...61  \x30 ... \x39     '0'...'9'  '0'...'9'
    62    \x2F vs. \x2D  →   '/' (2F)   '-' (2D)
    63    \x2B vs. \x5F  →   '+' (2B)   '_' (5F)

替换可能是由于以下事实:出于某种原因,RFC4648选择了两个字符,这些字符在URL中已经具有突出的和完善的功能。[注1.]显然,对于此处讨论的用法,最好避免这种特殊的并发症。

与官方规范的另一个区别是YouTube标识符不使用=填充字符;没必要,因为每个解码后的整数大小所期望的编码长度是固定且已知的(分别针对64位和128位为11和22个编码的“数字”)。

除一个较小的例外(如下所述)外,可以从可公开访问的数据推断出Base64映射的完整细节。通过最少的猜测,videoIdchannelId字符串中使用的Base64方案可能如下所示:

    ——₀————₁————₂————₃————₄————₅————₆————₇————₈————₉———₁₀———₁₁———₁₂———₁₃———₁₄———₁₅—
     00ᴴ  01ᴴ  02ᴴ  03ᴴ  04ᴴ  05ᴴ  06ᴴ  07ᴴ  08ᴴ  09ᴴ  0Aᴴ  0Bᴴ  0Cᴴ  0Dᴴ  0Eᴴ  0Fᴴ
00→ 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
      A    B    C    D    E    F    G    H    I    J    K    L    M    N    O    P

    —₁₆———₁₇———₁₈———₁₉———₂₀———₂₁———₂₂———₂₃———₂₄———₂₅———₂₆———₂₇———₂₈———₂₉———₃₀———₃₁—
     10ᴴ  11ᴴ  12ᴴ  13ᴴ  14ᴴ  15ᴴ  16ᴴ  17ᴴ  18ᴴ  19ᴴ  1Aᴴ  1Bᴴ  1Cᴴ  1Dᴴ  1Eᴴ  1Fᴴ
01→ 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
      Q    R    S    T    U    V    W    X    Y    Z    a    b    c    d    e    f

    —₃₂———₃₃———₃₄———₃₅———₃₆———₃₇———₃₈———₃₉———₄₀———₄₁———₄₂———₄₃———₄₄———₄₅———₄₆———₄₇—
     20ᴴ  21ᴴ  22ᴴ  23ᴴ  24ᴴ  25ᴴ  26ᴴ  27ᴴ  28ᴴ  29ᴴ  2Aᴴ  2Bᴴ  2Cᴴ  2Dᴴ  2Eᴴ  2Fᴴ
10→ 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
      g    h    i    j    k    l    m    n    o    p    q    r    s    t    u    v

    —₄₈———₄₉———₅₀———₅₁———₅₂———₅₃———₅₄———₅₅———₅₆———₅₇———₅₈———₅₉———₆₀———₆₁———₆₂———₆₃—
     30ᴴ  31ᴴ  32ᴴ  33ᴴ  34ᴴ  35ᴴ  36ᴴ  37ᴴ  38ᴴ  39ᴴ  3Aᴴ  3Bᴴ  3Cᴴ  3Dᴴ  3Eᴴ  3Fᴴ
11→ 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
      w    x    y    z    0    1    2    3    4    5    6    7    8    9    -    _

相信使用Base64的原因是,当我们假设编码器输入的标准整数大小分别为64位和128位时,Base64会准确预测YouTube channelIdvideoId标识符的异常字符长度(11和22个字符)。此外,根据Base64计算得出的余数可以完美地解释在每种类型的标识符字符串的l founda̲s̲t̲ c̲h̲a̲r̲a̲c̲t̲e̲r̲中发现的观察到的分布变化。这些问题的讨论如下。

在这两种情况下,分别针对videoIdchannelId进行Base64编码的二进制“数据”是64或128位的单个整数。因此,通过使用Base64解码器,可以从字符串标识符中恢复单个整数,并且这样做非常有用,因为尽管每个整数id都包含与Base64字符串完全相同的信息,并且还允许该字符串可以随时重新创建-与以Unicode形式存储的Base64字符串相比,二进制表示形式小63%,最大位密度为100%,在内存中的对齐方式更好,排序和散列处理更快,并且也许最重要的是,消除了仅在正交情况下不同的标识符之间的错误冲突。这最后一个问题,虽然极不可能的数字,但不能排除当Base64编码ID是不区分大小写处理,因为一些文件系统做(如视窗,可以追溯到DOS)。

这很重要:如果您将videoId / channelId字符串用作Windows / NTFS文件名的一部分,则由于文件系统部署了不区分大小写的路径和文件命名而导致文件名冲突的可能性微乎其微,但非零

如果您担心这个遥远的问题,可以用数学方法消除它的一种方法是将解码后的整数(仍按本文所述获得)重新编码为10进制(十进制)或(均匀-十六进制表示形式,用于此类文件系统上的路径或文件名。[注2]。在这种方法中,64位videoId将需要20个十进制数字[0-9]或8个十六进制数字[0-9,A-F]相对于 11个Base64数字)。128位channelId最多需要39个十进制数字或16个十六进制数字( 22个Base64数字)。

对于64位情况,解码为二进制很简单,因为您可以使用UInt64ulongC#中)保留返回的本机二进制值。

/// <summary> Recover the unique 64-bit value from an 11-character videoID </summary>
/// <remarks>
/// The method of padding shown here (i.e. 'b64pad') is provided to demonstrate the
/// full and correct padding requirement for Base64 in general. For our cases:
///
///    videoId    →  11 chars  →  b64pad[11 % 3]  →  b64pad[2]  →  "="
///    channelId  →  22-chars  →  b64pad[22 % 3]  →  b64pad[1]  →  "=="
///
/// Note however that, because it returns 'ulong', this function only works for videoId 
/// values, and the padding will always end up being "=". This is assumed in the revised
/// version of this code given further below, by just hard-coding the value "=".
/// </remarks>

static ulong YtEnc_to_videoId(String ytId)
{
    String b64 = ytId.Replace('-', '+').Replace('_', '/') + b64pad[ytId.Length % 3];

    return BitConverter.ToUInt64(Convert.FromBase64String(b64), 0);
}

static String[] b64pad = { "", "==", "=" };

对于128位值,这有点棘手,因为除非编译器具有__int128表示形式,否则您必须找出一种存储整个事物并在传递时保持组合状态的方法。一个简单的值类型(或System.Numerics.Vectors.Vector<T>,如果可用,则显示为128位SIMD硬件寄存器)将在.NET中发挥作用(未显示)。

[ 编辑: ]
进一步的思考后,我原来的职位的一部分是不完整的最大。为了公平起见,保留了原始摘录(如果需要,您可以跳过它);我在下面立即解释缺少的见解:

[ 原文: ]
上面您可能已经注意到我写过您可以恢复“ a ”整数。这不是最初编码的值吗?不必要。而且我并不是在暗示有符号/无符号的区别,这是真的,在这里无法确定(因为它不会改变有关二进制映像的任何事实)。它本身就是数值:没有一些“ Rosetta Stone”“,这样我们就可以对绝对值为“正确”的绝对值进行交叉检查,无法肯定地知道数字字母映射以及字节序,这意味着我们无法保证您会恢复与幸运的是,只要YouTube从未在其他地方公开以不太透明的格式公开所谓的正确值,那就没关系了。

那是因为解码后的64位或128位值除了用作标识令牌外没有其他用途,因此我们对转换的唯一要求是不同的编码(没有两个唯一的令牌发生冲突)和可逆性(解码可恢复原始令牌标识)。

换句话说,我们真正关心的只是原始Base64字符串的无损往返。由于Base64是无损且可逆的(只要您在编码和解码时始终坚持相同的字母映射和字节序假设),就可以满足我们的目的。您的数值可能与YouTube主保管库中记录的数值不匹配,但是您将无法分辨出任何差异。


[ 新分析: ]
事实证明,有一些线索,可以告诉我们关于“真实” 的Base64映射。只有某些映射可以预测我们观察到的最终位置字符,这意味着仅那些字符的二进制值必须具有一定数量的LSB零。h

结合绝大多数以字母和数字字符按升序映射的假设,我们基本上可以确认该映射为上表所示。关于LSB分析不确定的唯一剩下的不确定因素是可能替换-_字符(62/ 63)。

原始文本确实讨论了这个LSB问题(请参阅下文),但是当时我还没有完全意识到LSB信息如何作用以限制可能的Base64映射。

最后对此的评论是,您实际上可能想要故意选择 big-endian作为您的应用在内部使用的二进制解释(尽管如今它不如little-endian常见,因此可能不是YouTube“正式”使用的方式)它)。原因是这是在相同值上出现双重视图的情况,因此实际字节顺序在Base64格式中明显可见。保持二进制值和(更多)人类可读的Base64字符串之间的排序顺序一致是有用的,而且不会造成混乱,但是little-endian二进制值的排序是所需ASCII /词法排序的不平凡的争夺。

如果从小尾数ID值开始(即简单地反转它们的排序将不起作用),则没有针对此问题的简单解决方案。相反,您必须提前计划并在解码时反转每个二进制值的字节。因此,如果您关心与二进制值的排序匹配的字母显示,则可能需要更改上面显示的函数,以便将其解码为big-endian ulong值。这是代码:

// Recover the unique 64-bit value (big-endian) from an 11-character videoID
static ulong YtEnc_to_videoId(String ytId)
{
    var a = Convert.FromBase64String(ytId.Replace('-', '+').Replace('_', '/') + "=");
    if (BitConverter.IsLittleEndian)   // true for most computers nowadays
        Array.Reverse(a); 
    return BitConverter.ToUInt64(a, 0);
}


YouTube ID


影片编号

对于videoId,它是一个8字节(64位)的整数。将Base64编码应用于8个字节的数据需要11个字符。但是,由于每个Base64字符正好传达6位(即11 × 6 = 662 2 等于64),所以这种分配实际上可以容纳位,比有效负载所需的64位多2位。多余的位设置为零,这具有排除某些字符永远不会出现在编码字符串的最后位置的作用。特别是,保证videoId始终以以下字符之一结尾:

{ A, E, I, M, Q, U, Y, c, g, k, o, s, w, 0, 4, 8 }

因此,videoId的最大约束正则表达式(RegEx)将如下所示:

[0-9A-Za-z_-]{10}[048AEIMQUYcgkosw]


频道或播放列表ID

所述的channelIDplaylistId串被编码的Base64 128位(16字节)的二进制整数制造。这提供了一个22个字符的字符串,该字符串可以加上前缀UC以标识频道本身,或带有UU标识所包含视频的完整播放列表。这些24个字符的前缀字符串用于URL中。例如,下面显示了两种引用同一通道的方法。请注意,播放列表版本显示了频道中的视频总数,[请参阅注3],这是频道页面未公开的有用信息。

频道网址
https://www.youtube.com/channel/UC K8sQmJBp8GCxrOtXWBpyEA
播放清单网址
https://www.youtube.com/playlist?list=UU K8sQmJBp8GCxrOtXWBpyEA

与11个字符的videoId一样,根据Base64计算可以正确预测观察到的22个字符的字符串长度。在这种情况下,输出能够22 × 6 = 132对4位的剩余位进行编码;这些零最终限制了64个字母符号中的m̲o̲s̲t̲出现在最后一个位置,仅剩下4个符合条件。因此,我们知道YouTube channelId字符串中的最后一个字符必须为以下字符之一:

{ A, Q, g, w }

这为我们提供了channelId的最大约束正则表达式:

[0-9A-Za-z_-]{21}[AQgw]

最后一点,上面显示的正则表达式仅描述了裸ID值,没有URL,其他用途中必须存在的前缀,斜杠,分隔符等。在给定标识符字符串的属性的情况下,我介绍的RegEx模式在数学上尽可能地小,但是如果按原样使用而没有其他上下文,则它们可能会生成很多错误的肯定信息,即:错误地匹配了虚假文本。为避免在实际使用中出现此问题,请将它们尽可能多地包含在预期的相邻上下文中。


注意事项

[1.]
如上所述,这是Base64规范的摘录,其中讨论了选择字母符号时的注意事项。试图了解该过程如何在选择具有URL语义的字符时得出结论的个人可能会发现这些解释有些没有道理。

3.4。选择字母

不同的应用程序对字母中的字符有不同的要求。以下是确定应使用哪个字母的一些要求:

  • 由人类处理。字符“ 0”和“ O”以及“ 1”,“ l”和“ I”很容易混淆。在下面的base32字母表中,其中不存在0(零)和1(一),根据情况,解码器可以将0解释为O,将1解释为I或L。(但是,默认情况下它不应该;请参阅上一节。)

  • 编码为要求其他要求的结构。对于基数16和基数32,这确定使用大写或小写字母。对于基数64,非字母数字字符(特别是“ /”)在文件名和URL中可能会出现问题。

  • 用作标识符。某些字符,特别是基数为64的字母中的“ +”和“ /”,被传统文本搜索/索引工具视为断字。

没有能够满足所有要求的公认字母。有关高度专业化变体的示例,请参见IMAP [8]。在本文档中,我们记录并命名了一些当前使用的字母。

[2.]
或者,要解决使用Base64编码的ID字符串作为NTFS文件系统上文件或路径名的“原样”组成部分的问题,默认情况下,该字符串不区分大小写(因此在技术上可能会混淆一个或多个)不相关的ID值),这样就可以对NTFS 进行按卷区分大小写的路径/文件命名配置。启用非默认行为可以解决此处描述的问题,但是极少推荐使用此方法,因为它会更改对检查或访问该卷的所有/所有不同应用程序的期望。如果您甚至正在考虑使用此选项,请先阅读并理解它,然后您可能会改变主意。

[3.]
我认为,频道播放列表页面上显示的视频总数考虑了根据HTTP客户端的地理区域限制的视频排除范围。这说明了为播放列表和频道列出的视频数量之间的差异。


3
那是一些令人印象深刻的侦探工作。
ale

3
鳄梨调味酱,这个答案值得一千个投票
pilau

YouTube频道ID现在为24个字符,而不是22个字符;例如UCjXfkj5iapKHJrhYfAF9ZGg;来源:stackoverflow.com/questions/14366648/…–
evandrix

1
@evandrix感谢您的来信。我帖子的最后一段旨在解决这个问题;我只讨论ID字符串的可变部分。有通道ID的前缀(例如UCUU),本文中不再讨论。如果您有带前缀的值(例如您的示例),则我提供的信息适用于最后22个字符。
格伦·斯莱登

1
@evandrix如果您仍然感兴趣,我刚刚更新了文章本身,以包含有关UC vs. UU channelId前缀的信息。
Glenn Slayden
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.