Chaque vidéo YouTube a un identifiant unique qui peut être utilisé pour y accéder. Par exemple, la vidéo sur http://www.youtube.com/watch?v=aN46pEO_jX8
a l'id aN46pEO_jX8
.
Après quelques observations, il me semble que ces identifiants obéissent aux deux règles suivantes:
Je veux savoir:
Selon Youtube documentation de l'API 2. et documentation de l'API 3. , le videoId est une chaîne, rien n'est précisé sur le jeu de caractères actuellement utilisé ...
A propos de la longueur de 11 caractères, un message d'une équipe d'API Youtube dire:
Je ne vois nulle part dans la documentation où nous nous engageons officiellement à utiliser une longueur standard de 11 caractères pour les identifiants de vidéos YouTube. C’est l’une de ces choses pour lesquelles nous avons mis en place une solution actuelle, qui pourrait rester indéfiniment. Mais nous ne proposons aucun engagement officiel à cet égard, alors procédez à vos risques et périls.
Et le dernier mais non le moindre, n autre message clarifie (ou non) le format:
Nous ne donnons aucune garantie publique sur le format des identifiants vidéo. Bien qu'il s'agisse actuellement de 11 chaînes de caractères contenant des lettres, des chiffres et des signes de ponctuation, je ne recommanderais pas de coder cela dans votre application (à moins que vous ne puissiez facilement le changer à l'avenir).
L'équipe Youtube semble préférer demander directement au serveur Youtube si le Video_ID est correct ou non (se référer à une vidéo existante):
Si vous devez valider que cette entrée utilisateur aléatoire correspond à un identifiant vidéo valide, je vous recommande de faire un test empirique. Tentative d'accès
http://gdata.youtube.com/feeds/api/videos/VIDEO_ID
Si vous obtenez une réponse de 200, alors VIDEO_ID est valide. Si vous obtenez une réponse non-200, vous avez un identifiant invalide. Il existe certains cas Edge pour les vidéos nouvellement téléchargées ou les vidéos privées, mais dans la plupart des cas, je suppose que cela irait.
Les identifiants YouTube videoIdet channelIdsont des valeurs entières uniques représentées dans une version légèrement modifiée de encodage en Base64 . Une différence par rapport au recommandations IETF RFC4648 est la substitution de deux caractères dans l’alphabet de codage:
_ 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)
_
La substitution est probablement due au fait que, pour une raison quelconque RFC4648 sélectionné deux caractères qui avaient déjà des fonctions bien en évidence et bien établies dans les URL.[note 1.] De toute évidence, pour l’usage en discussion ici, il était préférable d’éviter cette complication particulière.
Une autre différence par rapport à la spécification officielle est que les identifiants YouTuben'utilisent pas le caractère de remplissage _=
_; ce n'est pas nécessaire car les longueurs codées attendues par taille d'entier décodée respective sont fixes et connues (11 et 22 "chiffres" codés pour 64 et 128 bits, respectivement).
À une exception mineure (voir ci-dessous), les détails complets du mappage Base64 peuvent être déduits à partir de données accessibles au public. Avec un minimum de devinettes, il est probable que le schéma Base64utilisé dans le videoIdet channelIdstrings est comme suit:
_ ——₀————₁————₂————₃————₄————₅————₆————₇————₈————₉———₁₀———₁₁———₁₂———₁₃———₁₄———₁₅—
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 - _
_
La raison de croire que Base64 est utilisé est que, lorsque nous supposons des tailles d’entiers standard de 64 et 128 bits pour l’entrée du codeur, Base64 prédit les longueurs de caractères inhabituelles (11 et 22 caractères) de YouTube channelIdet videoIdidentifiants exactement. De plus, les restes calculés selon Base64 expliquent parfaitement la variation de distribution observée observée dans lela̲s̲t̲ ch̲a̲r̲act̲er̲de chaque type de chaîne d'identificateur. La discussion de ces points suit.
Dans les deux cas, les "données" binaires codées en Base64 sont un seul entier, soit 64 ou 128 bits, pour (respectivement) videoIdvs. channelId. En conséquence, en utilisant un décodeur Base64, un seul entier peut être récupéré à partir de l'identificateur de chaîne. Cela peut s'avérer très utile car, bien que chaque id d'entier contienne exactement les mêmes informations que la chaîne Base64, il permet également à la chaîne de être recréé à tout moment - par rapport aux chaînes Base64 stockées en Unicode, la représentation binaire est 63% plus petite, a une densité de bits maximale de 100%, aligne mieux la mémoire, trie et hachage plus rapidement et, ce qui est peut-être le plus important, élimine fausses collisions entre identifiants qui ne diffèrent que par cas orthographique . Ce dernier problème, même s’il est extrêmement improbable numériquement, ne peut néanmoins pas être exclu lorsque les ID Base64 sont traités comme respectant la casse, comme le font certains systèmes de fichiers (par exemple Windows , remontant à DOS ).
C'est un peu important: si vous utilisez une chaîne videoId/ channelIddans le cadre d'un nom de fichier Windows/NTFS, il existe un minuscule -mais néanmoins non-zéro- risque de collisions de noms de fichiers dû au fait que ces systèmes de fichiers déploient des noms de chemins et de fichiers insensibles à la casse. Si vous êtes inquiet au sujet de ce problème possible à distance, une façon de l'éliminer mathématiquement serait d'utiliser à la place la représentation hexdécimale en base 10 (décimale) ou (en cascade uniforme) des entiers décodés, obtenue comme décrit dans cet article, en chemins ou noms de fichiers sur ces systèmes de fichiers.[note 2.]
Le décodage en binaire est trivial pour les 64 bitscase car vous pouvez utiliser un _UInt64
_ (ulong
dans C #) pour contenir la valeur binaire native qui revient.
_/// <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 = { "", "==", "=" };
_
Pour le cas des valeurs 128-bit, c'est un peu plus compliqué car, à moins que votre compilateur ait une représentation ___int128
_, vous devrez trouver un moyen de stocker le le tout et conservez-le combobulé lorsque vous le faites circuler. Un type de valeur simple (ou System.Numerics.Vectors.Vector<T>
, qui se présente sous la forme d'un registre matériel SIMD 128 bits, le cas échéant) fera l'affaire en .NET (non illustré).
[ edit:]
Après mûre réflexion, une partie de mon message original n’était pas totalement complète. Par souci d'équité, l'extrait original est conservé (vous pouvez le sauter si vous le souhaitez); immédiatement ci-dessous, j'explique l'insight manquant:[ original:]
Vous avez peut-être remarqué plus haut que j'ai écrit que vous pouvez récupérer un entier "an". Ne serait-ce pas la valeur encodée à l'origine? Pas nécessairement. Et je ne fais pas allusion à la distinction signée/non signée qui, il est vrai, ne peut pas être vérifiée ici (car elle ne modifie aucun fait concernant l'image binaire). Ce sont les valeurs numériques elles-mêmes: Sans quelque " Rosetta Stone " qui nous permettrait de vérifier par recoupement avec les valeurs absolues connues pour être "correctes", le mappage de l'alphabet numérique et aussi le caractère final ne peuvent pas être positivement connu, ce qui signifie qu'il n'y a aucune garantie que vous récupériez la même valeur que celle encodée par les ordinateurs de YouTube. Heureusement, tant que YouTube n'exposera jamais publiquement les valeurs dites correctes dans un format moins opaque, cela n'a aucune importance.C’est parce que les valeurs décodées de 64 ou 128 bits n’ont d’utilité que comme jetons d’identification. Nos seules exigences en matière de transformation sont donc:codage distinct(pas de deux jetons uniques). collide) etréversibilité(le décodage récupère l'identité du jeton d'origine).
En d'autres termes, tout ce qui nous intéresse, c'est de allers-retours sans pertede la chaîne Base64 d'origine. Puisque Base64 est sans perte et réversible (tant que vous vous en tenez toujours au même mappage d’alphabets et endianness hypothèse pour l’encodage et le décodage), il répond à nos objectifs. Vos valeurs numériques peuvent ne pas correspondre à celles enregistrées dans le coffre-fort principal de YouTube, mais vous ne pourrez faire aucune différence.
[ nouvelle analyse:]
Il s'avère quesontquelques indices pouvant nous renseigner sur le "vrai" Base64mapping . Seules certaines correspondances prédisent les caractères de position finale observés, c'est-à-dire que la valeur binaire deseuls ces caractèresdoit comporter un certain nombre de zéros LSB. Il h.Compte tenu de l'hypothèse la plus plausible selon laquelle les caractères de l'alphabet et des chiffres sont mappés par ordre croissant, nous pouvons essentiellement confirmer que la mappage correspond à ce qui est présenté dans les tableaux ci-dessus. La seule incertitude qui reste à propos de laquelle l'analyse LSB n'est pas concluante est l'échange possible des caractères _
-
_ et __
_ (_62
_/_63
_).Le texte originaladiscute de cette question de LSB (voir ci-dessous), mais ce que je ne savais pas tout à fait à l'époque, c'était comment les informations de LSB agissaient pour limiter le Base64mappings.
Un dernier commentaire à ce sujet est que vous pourriez en fait vouloir choisir intentionnellement big-endian pour l'interprétation binaire avec laquelle votre application fonctionne en interne (même si elle est moins courante que little-endian = de nos jours et donc peut-être pas la façon dont YouTube "officiellement" le fait). La raison en est qu’il s’agit d’un cas de vues doubles sur la même valeur, de sorte que l’ordre réel des octets est exposé de manière visible dans le rendu Base64. Il est utile et moins déroutant de conserver la ordre de tricohérente entre la valeur binaire et la base (légèrement plus) lisible par l'homme64 string, mais le type des valeurs binaires little-endian est un embrouillage non trivial du type ASCII/lexical souhaité.
Il n’ya pas de solution simple à ce problème si vous commencez avec des valeurs d’identité little-endian (c’est-à-dire qu’il est impossible d’inverser leur tri) Au lieu de cela, vous devez planifier et inverser les octets de chaque valeur binaireau moment du décodage. Donc, si vous vous souciez de l'affichage alphabétique correspondant au tri des valeurs binaires, vous voudrez peut-être modifier la fonction présentée ci-dessus afin qu'elle soit décodée en big-endianulong
valeurs à la place. Voici ce code:
_// 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);
}
_
Id vidéo
Pour videoId, il s'agit d'un entier de 8 octets (64 bits). L'application du codage Base64 à 8 octets de données nécessite 11 caractères. Cependant, comme chaque caractère Base64 véhicule exactement 6 bits (à savoir, 2⁶ équivaut à 64), cette allocation pourrait contenir jusqu'à _11 × 6 = 66
_ bits, soit un excédent de 2 bits sur les 64 bits dont notre charge utile a besoin. Les bits en excès sont mis à zéro, ce qui a pour effet d'empêcher certains caractères d'apparaître à la dernière position de la chaîne codée. En particulier, le videoIdest garanti pour toujours se terminer par l'un des caractères suivants:
_{ A, E, I, M, Q, U, Y, c, g, k, o, s, w, 0, 4, 8 }
_
Ainsi, l'expression régulière (RegEx) à contrainte maximale pour le videoIdserait la suivante:
_[0-9A-Za-z_-]{10}[048AEIMQUYcgkosw]
_
Identifiant de chaîne ou de liste de lecture
Les chaînes channelIdet playlistIdsont générées en codant en Base64 un entier binaire de 128 bits (16 octets). Cela donne une chaîne de 22 caractères qui peut être préfixé soit par UC
pour identifier le canal lui-même, soit par UU
pour identifier une liste de lecture complète des vidéos qu'il contient. Ces chaînes préfixées de 24 caractères sont utilisées dans URL. Par exemple, ce qui suit montre deux manières de se référer au même canal. Notez que la version de la liste de lecture indique le nombre total de vidéos du canal,[voir note 3.] une information utile que les pages de la chaîne n'exposent pas.
URL de la chaînehttps://www.youtube.com/channel/UC K8sQmJBp8GCxrOtXWBpyEAURL de la liste de lecturehttps://www.youtube.com/playlist?list=UU K8sQmJBp8GCxrOtXWBpyEA
Comme ce fut le cas pour le vidéoIdà 11 caractères, le calcul selon Base64 prédit correctement la longueur de chaîne observée de à 22 caractères. Dans ce cas, la sortie est capable de coder _22 × 6 = 132
_ bits, un surplus de 4 bits; ces zéros finissent par limiter la m̲o̲s̲t des 64 symboles de l'alphabet à la dernière position, avec seulement 4 restants éligibles. Nous savons donc que le dernier caractère d'une chaîne YouTube channelIddoit être l'un des suivants:
_{ A, Q, g, w }
_
Cela nous donne l'expression régulière contrainte au maximum pour un channelId:
_[0-9A-Za-z_-]{21}[AQgw]
_
En guise de conclusion, les expressions régulières ci-dessus ne décrivent que les valeurs nues, sans les préfixes, les barres obliques, les séparateurs, etc., qui doivent figurer dans les URL et les autres utilisations. Les modèles RegEx que j'ai présentés sont aussi mathématiquement minimaux que possible compte tenu des propriétés des chaînes d'identifiant, mais s'ils sont utilisés tels quels sans contexte supplémentaire, ils généreront probablement beaucoup de faux positifs, à savoir: faire une mauvaise correspondance avec le texte parasite. Pour éviter ce problème en utilisation réelle, entourez-les autant que possible du contexte adjacent attendu.
Notes
[1.]
Comme promis ci-dessus, voici un extrait de la spécification Base64 qui traite de leurs considérations lors de la sélection des symboles de l’alphabet. Les personnes cherchant à comprendre comment le processus a abouti à la sélection de caractères avec la sémantique des URL peuvent trouver les explications quelque peu peu édifiantes.
3.4. Choisir l'alphabet
Différentes applications ont des exigences différentes sur les caractères de l'alphabet. Voici quelques exigences qui déterminent quel alphabet doit être utilisé:
Manipulé par des humains. Les caractères "0" et "O" se confondent facilement, de même que "1", "l" et "I". Dans l'alphabet base32 ci-dessous, où 0 (zéro) et 1 (un) ne sont pas présents, un décodeur peut interpréter 0 comme étant O et 1 comme I ou L, selon le cas. (Cependant, par défaut, cela ne devrait pas être; voir la section précédente.)
Encodé dans des structures qui imposent d'autres exigences. Pour les bases 16 et 32, cela détermine l’utilisation des alphabets majuscules ou minuscules. Pour la base 64, les caractères non alphanumériques (en particulier "/") peuvent poser problème dans les noms de fichier et les URL.
Utilisé comme identifiant. Certains caractères, notamment "+" et "/" dans l'alphabet en base 64, sont traités comme des sauts de mots par les outils de recherche/index de texte hérités.
Il n'y a pas d'alphabet universellement accepté qui remplisse toutes les conditions. Pour un exemple de variante hautement spécialisée, voir IMAP [8]. Dans ce document, nous documentons et nommons certains alphabets actuellement utilisés.
[2.]
Vous pouvez également résoudre le problème de l’utilisation de chaînes d’identification codées en Base64 en tant que composants "tels quels" des noms de fichiers ou de chemins sur le système de fichiers NTFS, qui ne fait pas la distinction entre les majuscules et les minuscules par défaut (et risque donc techniquement de confondre un ou plusieurs fichiers). plusieurs ID non liés), il se trouve que NTFS peut être configuré avec un nom de chemin/fichier respectant la casse sur une base par volume. L'activation du comportement autre que celui par défaut peut résoudre le problème décrit ici, mais elle est rarement recommandée car elle modifie les attentes pour toutes les applications disparates qui inspectent ou accèdent au volume. Si vous envisagez même cette option, lisez et comprenez ceci d’abord, et vous allez probablement changer d’avis.
[3.]
Je pense que le nombre total de vidéos affichées dans la page de liste de lecture de la chaîne prend en compte une exclusion des vidéos restreintes en fonction de la région géographique du client HTTP. Cela représente toute différence entre le nombre de vidéos répertoriées pour la liste de lecture et le canal.