YouTube- Video-ID- und -Kanal- ID-ID- IDs sind einzelne Ganzzahlwerte, die in einer leicht geänderten Version der Base64-Codierung dargestellt werden . Ein Unterschied zu den IETF RFC4648-Empfehlungen besteht in der Ersetzung von zwei Zeichen im Kodierungsalphabet:
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)
Die Substitution ist wahrscheinlich auf die Tatsache zurückzuführen, dass RFC4648 aus irgendeinem Grund zwei Zeichen auswählte, die in URLs bereits bekannte und gut etablierte Funktionen hatten. [Anmerkung 1.] Offensichtlich wurde für die hier diskutierte Verwendung diese besondere Komplikation am besten vermieden.
Ein weiterer Unterschied zur offiziellen Spezifikation besteht darin, dass YouTube- Bezeichner das =
Füllzeichen nicht verwenden . Dies ist nicht erforderlich, da die zu erwartenden codierten Längen für die jeweilige decodierte Ganzzahlgröße fest und bekannt sind (11 und 22 codierte 'Ziffern' für 64 bzw. 128 Bit).
Mit einer kleinen Ausnahme (siehe unten) können die vollständigen Details der Base64-Zuordnung aus öffentlich zugänglichen Daten abgeleitet werden. Mit einem Minimum an Rätselraten ist es wahrscheinlich, dass das in den videoId- und channelId- Zeichenfolgen verwendete Base64- Schema wie folgt lautet:
——₀————₁————₂————₃————₄————₅————₆————₇————₈————₉———₁₀———₁₁———₁₂———₁₃———₁₄———₁₅—
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 - _
Der Grund für die Annahme, dass Base64 verwendet wird, besteht darin, dass Base64, wenn für die Encodereingabe ganzzahlige Standardgrößen von 64 und 128 Bit angenommen werden, die ungewöhnlichen Zeichenlängen (11 und 22 Zeichen) der YouTube- ChannelId- und -VideoId- Bezeichner genau vorhersagt . Darüber hinaus erklären Reste, die gemäß Base64 berechnet wurden, die beobachteten Verteilungsschwankungen, die im l ina̲s̲t̲ c̲h̲a̲r̲a̲c̲t̲e̲r̲ der einzelnen Typen von Bezeichnerzeichenfolgen zu finden sind, perfekt . Die Diskussion dieser Punkte folgt.
In beiden Fällen sind die binären "Daten", die Base64-codiert werden, eine einzelne Ganzzahl (64 oder 128 Bit) für (jeweils) videoId vs. channelId . Unter Verwendung eines Base64-Decoders kann dementsprechend eine einzelne Ganzzahl aus dem Zeichenfolgenbezeichner wiederhergestellt werden. Dies kann sehr nützlich sein, da jede Ganzzahl-ID genau die gleichen Informationen enthält wie die Base64-Zeichenfolge - und dies auch zulässt jederzeit neu erstellt werden - im Vergleich zu Base64-Zeichenfolgen, die als Unicode gespeichert sind, ist die Binärdarstellung 63% kleiner, hat eine maximale Bitdichte von 100%, richtet sich im Speicher besser aus, sortiert und hascht schneller und beseitigt möglicherweise das Wichtigste falsche Kollisionen zwischen Bezeichnern, die sich nur im orthografischen Fall unterscheiden. Dieses letzte Problem ist zwar zahlenmäßig äußerst unwahrscheinlich, kann jedoch nicht ausgeschlossen werden, wenn Base64-IDs wie bei einigen Dateisystemen (z. B. Windows , das auf DOS zurückgeht ) als nicht von Groß- und Kleinschreibung abhängig behandelt werden .
Das ist ein bisschen wichtig: Wenn Sie eine videoId / channelId- Zeichenfolge als Teil eines Windows- / NTFS-Dateinamens verwenden, ist die Wahrscheinlichkeit von Dateinamenskollisionen auf Grund der Dateisysteme, bei denen die Groß- und Kleinschreibung nicht beachtet wird, sehr gering .
Wenn Sie sich über dieses remote mögliche Problem Sorgen machen, besteht eine Möglichkeit, es mathematisch zu beseitigen, darin, die decodierten Ganzzahlen, die immer noch wie in diesem Artikel beschrieben erhalten werden, in eine Base-10-Zahl (dezimal) oder eine (einheitliche Zahl) umzucodieren. hexadezimale Darstellung, zur Verwendung in Pfad- oder Dateinamen auf solchen Dateisystemen. [Anmerkung 2.] Bei diesem Ansatz würde die 64-Bit- Video - ID 20 Dezimalstellen [0-9]
oder 8 Hexadezimalstellen[0-9,A-F]
( gegenüber 11 Base64-Stellen) benötigen . Die 128-Bit- Kanal - ID erfordert maximal 39 Dezimalstellen oder 16 Hexadezimalstellen ( gegenüber 22 Base64-Stellen).
Die Dekodierung in Binärdateien ist für den 64-Bit- Fall trivial, da Sie mit UInt64
( ulong
in C # ) den zurückkommenden nativen Binärwert speichern können.
/// <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 = { "", "==", "=" };
Für den Fall der 128-Bit- Werte ist dies etwas schwieriger, da Sie, sofern Ihr Compiler keine __int128
Repräsentation hat, eine Möglichkeit finden müssen, das Ganze zu speichern und es beim Weitergeben kombiniert zu halten . Ein einfacher Wertetyp (oder System.Numerics.Vectors.Vector<T>
, falls verfügbar, ein 128-Bit-SIMD-Hardwareregister) erledigt den Trick in .NET (nicht gezeigt).
[ edit: ]
Nach weiteren Überlegungen war ein Teil meines ursprünglichen Beitrags nicht vollständig. Der Fairness halber wird der Originalauszug beibehalten (Sie können ihn bei Bedarf überspringen). Gleich unten erkläre ich die fehlende Einsicht:
[ original: ]
Sie haben vielleicht oben bemerkt, dass ich geschrieben habe, dass Sie " eine " ganze Zahl wiederherstellen können . Wäre dies nicht der Wert, der ursprünglich codiert wurde? Nicht unbedingt. Und ich spreche nicht von der Unterscheidung zwischen signiert und nicht signiert, die hier zwar nicht festgestellt werden kann (weil sie nichts an den Fakten über das Binärbild ändert). Es sind die Zahlenwerte selbst: Ohne etwas " Rosetta Stone""Das würde es uns ermöglichen, mit Absolutwerten zu vergleichen, von denen bekannt ist, dass sie" korrekt "sind. Die Zuordnung des numerischen Alphabets und auch die Endianität können nicht eindeutig bestimmt werden, was bedeutet, dass es keine Garantie gibt, dass Sie den gleichen Wert wie diesen wiederherstellen Die Computer bei YouTube sind verschlüsselt. Solange YouTube die so genannten korrekten Werte in einem weniger undurchsichtigen Format an keiner anderen Stelle öffentlich zugänglich macht, spielt dies möglicherweise keine Rolle.
Dies liegt daran, dass die decodierten 64- oder 128-Bit-Werte ohnehin nur als Identifizierungstoken verwendet werden können. Unsere einzigen Anforderungen für die Transformation sind also eine eindeutige Codierung (keine Kollision zweier eindeutiger Token) und Reversibilität (die Decodierung stellt die ursprüngliche Token-Identität wieder her).
Mit anderen Worten, alles, was uns wirklich am Herzen liegt, ist das verlustfreie Auslösen der ursprünglichen Base64-Saite. Da Base64 verlustfrei und umkehrbar ist (solange Sie sich sowohl für die Codierung als auch für die Decodierung immer an die gleiche Alphabetzuordnung und Endianness- Annahme halten), erfüllt es unsere Zwecke. Ihre numerischen Werte stimmen möglicherweise nicht mit denen überein, die im Master-Tresor von YouTube aufgezeichnet wurden, Sie können jedoch keinen Unterschied feststellen.
[ Neue Analyse: ]
Es stellt sich heraus , dass es gibt ein paar Hinweise , die uns über das „wahre“ sagen können , Base64 - Mapping. Nur bestimmte Zuordnungen sagen die beobachteten Zeichen der Endposition voraus, dh, der Binärwert für nur diese Zeichen muss eine bestimmte Anzahl von LSB-Nullen aufweisen. Heh.
Zusammen mit der überwiegend wahrscheinlichen Annahme, dass die Zuordnung von Buchstaben und Ziffern in aufsteigender Reihenfolge erfolgt, können wir die Zuordnung im Grunde so bestätigen, wie sie in den obigen Tabellen dargestellt ist. Die einzige verbleibende Unsicherheit, über die die LSB-Analyse nicht schlüssig ist, ist der mögliche Austausch der Zeichen -
und _
( 62
/ 63
).
Der ursprüngliche Text hat diese LSB Ausgabe besprechen (siehe weiter unten), aber was habe mich nicht vollständig zu der Zeit erkennen war , wie LSB Informationen wirken die möglichen zu beschränken Base64 - Mappings.
Ein letzter Kommentar dazu ist, dass Sie möglicherweise absichtlich Big-Endian für die Binärinterpretation auswählen möchten, mit der Ihre App intern arbeitet (auch wenn dies heutzutage weniger verbreitet ist als Little-Endian und daher möglicherweise nicht die Art und Weise ist, wie YouTube dies "offiziell" tut es). Der Grund dafür ist, dass es sich um eine doppelte Ansicht mit demselben Wert handelt, sodass die tatsächliche Bytereihenfolge in der Base64-Wiedergabe sichtbar wird. Es ist hilfreich und weniger verwirrend, die Sortierreihenfolge zwischen dem Binärwert und dem (etwas besser) lesbaren Base64-String konsistent zu halten , aber die Sortierung der Little-Endian-Binärwerte ist eine nicht triviale Verwirrung der gewünschten ASCII- / Lexik-Sortierung .
Es gibt keine einfache Lösung für dieses Problem, wenn Sie mit Little-Endian-ID-Werten beginnen (dh das einfache Umkehren der Sortierung funktioniert nicht). Stattdessen müssen Sie die Bytes jedes Binärwerts zum Zeitpunkt der Dekodierung vorausplanen und umkehren . Wenn Sie also Wert darauf legen, dass die alphabetische Anzeige mit der Sortierung der Binärwerte übereinstimmt, möchten Sie möglicherweise die oben gezeigte Funktion so ändern, dass sie stattdessen in Big-Endian- ulong
Werte decodiert wird . Hier ist der 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);
}
YouTube-IDs
Video-ID
Bei der videoId handelt es sich um eine 8-Byte-Ganzzahl (64-Bit). Das Anwenden der Base64-Codierung auf 8 Datenbytes erfordert 11 Zeichen . Da jedoch jedes Base64-Zeichen genau 6 Bits überträgt (d. H. 2⁶ entspricht 64), könnte diese Zuordnung tatsächlich bis zu 11 × 6 = 66
Bits enthalten - ein Überschuss von 2 Bits gegenüber den 64 Bits, die unsere Nutzlast benötigt. Die überschüssigen Bits werden auf Null gesetzt, was dazu führt, dass bestimmte Zeichen nicht immer an der letzten Position der codierten Zeichenfolge erscheinen. Insbesondere wird garantiert , dass die videoId immer mit einem der folgenden Zeichen endet:
{ A, E, I, M, Q, U, Y, c, g, k, o, s, w, 0, 4, 8 }
Der maximal eingeschränkte reguläre Ausdruck (RegEx) für die videoId lautet daher wie folgt:
[0-9A-Za-z_-]{10}[048AEIMQUYcgkosw]
ID des Kanals oder der Wiedergabeliste
Die channelId und playlistId Strings werden durch Base64-kodiert , ein 128-Bit (16-Byte) binary integer. Dies ergibt eine 22-stellige Zeichenfolge, der entweder UC
der Kanal selbst oder UU
eine vollständige Wiedergabeliste der enthaltenen Videos vorangestellt werden kann . Diese Zeichenfolgen mit einem Präfix von 24 Zeichen werden in URLs verwendet . Im Folgenden werden beispielsweise zwei Möglichkeiten gezeigt, auf denselben Kanal zu verweisen. Beachten Sie, dass in der Playlist-Version die Gesamtzahl der Videos im Kanal angezeigt wird (siehe Hinweis 3). Dies ist eine nützliche Information, die auf den Kanalseiten nicht verfügbar gemacht wird.
Kanal-URLhttps://www.youtube.com/channel/UC K8sQmJBp8GCxrOtXWBpyEA
Playlist-URLhttps://www.youtube.com/playlist?list=UU K8sQmJBp8GCxrOtXWBpyEA
Wie bei der 11- stelligen videoId sagt die Berechnung pro Base64 die beobachtete Stringlänge von 22 Zeichen korrekt voraus . In diesem Fall ist der Ausgang in der Lage, 22 × 6 = 132
Bits zu codieren , ein Überschuss von 4 Bits; Diese Nullen schränken letztendlich das Erscheinen von m̲o̲s̲t̲ der 64 Alphabetsymbole an der letzten Position ein, wobei nur noch 4 zulässig sind. Wir wissen daher, dass das letzte Zeichen in einer YouTube- Kanal-ID eines der folgenden Zeichen sein muss:
{ A, Q, g, w }
Dies gibt uns den maximal eingeschränkten regulären Ausdruck für eine channelId :
[0-9A-Za-z_-]{21}[AQgw]
Als letzte Anmerkung beschreiben die oben gezeigten regulären Ausdrücke nur die bloßen ID-Werte ohne die Präfixe, Schrägstriche, Trennzeichen usw., die in URLs und den anderen verschiedenen Verwendungen vorhanden sein müssen. Die von mir vorgestellten RegEx-Muster sind in Anbetracht der Eigenschaften der Bezeichnerzeichenfolgen so mathematisch minimal wie möglich. Wenn sie jedoch ohne zusätzlichen Kontext verwendet werden, erzeugen sie wahrscheinlich viele falsch-positive Ergebnisse, dh, sie stimmen nicht mit falschem Text überein. Um dieses Problem bei der tatsächlichen Verwendung zu vermeiden, umgeben Sie sie so weit wie möglich mit dem erwarteten angrenzenden Kontext.
Anmerkungen
[1.]
Wie oben versprochen, finden Sie hier einen Auszug aus der Base64-Spezifikation, in dem die Überlegungen zur Auswahl der Alphabetsymbole erläutert werden. Personen, die verstehen möchten, wie der Prozess bei der Auswahl von Zeichen mit URL-Semantik abgeschlossen wurde, werden die Erklärungen möglicherweise als etwas unverbindlich empfinden.
3.4. Das Alphabet auswählen
Unterschiedliche Anwendungen stellen unterschiedliche Anforderungen an die Zeichen im Alphabet. Hier einige Anforderungen, die bestimmen, welches Alphabet verwendet werden soll:
Vom Menschen gehandhabt. Die Zeichen "0" und "O" sind leicht zu verwechseln, ebenso wie "1", "l" und "I". In dem unten stehenden base32-Alphabet, in dem 0 (Null) und 1 (Eins) nicht vorhanden sind, kann ein Decodierer 0 je nach Fall als 0 und 1 als I oder L interpretieren. (Standardmäßig sollte dies jedoch nicht der Fall sein; siehe vorherigen Abschnitt.)
Kodiert in Strukturen, die andere Anforderungen vorschreiben. Für Basis 16 und Basis 32 bestimmt dies die Verwendung von Groß- oder Kleinbuchstaben. Bei der Basis 64 können die nicht alphanumerischen Zeichen (insbesondere "/") in Dateinamen und URLs problematisch sein.
Wird als Bezeichner verwendet. Bestimmte Zeichen, insbesondere "+" und "/" im Basis-64-Alphabet, werden von älteren Textsuch- / Indextools als Wortumbrüche behandelt.
Es gibt kein allgemein anerkanntes Alphabet, das alle Anforderungen erfüllt. Ein Beispiel für eine hochspezialisierte Variante finden Sie in IMAP [8]. In diesem Dokument dokumentieren und benennen wir einige derzeit verwendete Alphabete.
[2.]
Alternativ können Sie das Problem der Verwendung von Base64-codierten ID-Zeichenfolgen als "as-is" -Komponenten von Datei- oder Pfadnamen im NTFS-Dateisystem lösen, bei dem standardmäßig die Groß- und Kleinschreibung nicht beachtet wird (und daher das Risiko besteht, dass eine oder mehrere Zeichen miteinander in Konflikt geraten (ID-Werte unabhängig) kann NTFS unter Berücksichtigung der Groß- und Kleinschreibung des Pfads / der Datei auf Volume-Basis konfiguriert werden . Das Aktivieren des nicht standardmäßigen Verhaltens behebt möglicherweise das hier beschriebene Problem, wird jedoch selten empfohlen, da es die Erwartungen für alle unterschiedlichen Anwendungen ändert, die das Volume überprüfen oder auf das Volume zugreifen. Wenn Sie diese Option überhaupt in Betracht ziehen, lesen und verstehen Sie dies zuerst, und Sie werden wahrscheinlich Ihre Meinung ändern.
[3.]
Ich glaube, die Gesamtzahl der auf der Playlistenseite des Kanals angezeigten Videos berücksichtigt einen Ausschluss für Videos, die gemäß der geografischen Region des HTTP-Clients eingeschränkt sind. Dies erklärt die Diskrepanz zwischen der Anzahl der für die Wiedergabeliste aufgelisteten Videos und dem Kanal.