Formato per ID del video di YouTube


32

Ogni video di YouTube ha un ID univoco che può essere utilizzato per ottenerlo. Ad esempio, il video su http://www.youtube.com/watch?v=aN46pEO_jX8ha l'id aN46pEO_jX8.

Dopo alcune osservazioni, mi sembra che questi ID obbediscano alle seguenti due regole:

  • Esattamente 11 caratteri
  • Simboli consentiti: az, AZ, 0-9, - e _

Voglio sapere:

  1. Se queste due regole sono sempre entrambe corrette.
  2. Se ci sono altre regole che sono importanti da seguire.

Risposte:


38

Secondo la documentazione dell'API di Youtube 2.0 e la documentazione dell'API 3.0 , il videoId è una stringa, non viene specificato nulla sull'insieme corrente di caratteri utilizzati ...

Circa la lunghezza di 11 caratteri, un post di un team API di Youtube dice:

Non vedo da nessuna parte nella documentazione in cui ci impegniamo ufficialmente con una lunghezza standard di 11 caratteri per gli ID video di YouTube. È una di quelle cose in cui abbiamo un'implementazione attuale e potrebbe rimanere così indefinitamente. Ma non stiamo offrendo alcun impegno ufficiale in tal senso, quindi procedi a tuo rischio.

E, ultimo ma non meno importante, un altro post chiarisce (o no) il formato:

Non forniamo garanzie pubbliche sul formato per gli ID video. Sebbene al momento siano 11 stringhe di caratteri che contengono lettere, numeri e alcuni segni di punteggiatura, non consiglierei di codificarlo nella tua applicazione (a meno che tu non abbia un modo semplice per cambiarlo in futuro).

Il team di Youtube sembra preferire chiedere direttamente al server Youtube se il Video_ID è corretto o meno (fare riferimento a un video esistente):

Se devi convalidare che l'input casuale dell'utente corrisponde a un ID video valido, ti consiglio di fare un test empirico. Tentativo di accesso

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

Se ricevi una risposta 200, allora VIDEO_ID è valido. Se ricevi una risposta diversa da 200, hai un ID non valido. Ci sono alcuni casi limite per i video appena caricati o i video privati, ma per la maggior parte dei casi suppongo che andrebbe bene.


Questa è un'ottima risposta e mi ha dato tutte le informazioni di cui avevo bisogno! Grazie!
Asfallows

3
Questo restituisce un HTTP 410 andato ora. Qualche idea su quale dovrebbe essere il nuovo URL per verificarlo ora?
Will Strohl,

1
Per verificare l'id video: basta ottenere la pagina HTML da YouTube e verificare che il collegamento meta canonico abbia lo stesso ID specificato.
puchu

50

Gli identificatori YouTube videoId e channelId sono valori interi singoli rappresentati in una versione leggermente modificata della codifica Base64 . Una differenza rispetto alle raccomandazioni IETF RFC4648 è la sostituzione di due caratteri nell'alfabeto di codifica:

 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 sostituzione è probabilmente dovuta al fatto che, per qualche motivo, RFC4648 ha selezionato due caratteri che avevano già funzioni prominenti e ben definite negli URL. [nota 1.] Ovviamente, per l'uso in discussione qui, quella particolare complicazione è stata meglio evitata.

Un'altra differenza rispetto alle specifiche ufficiali è che gli identificatori di YouTube non usano il =carattere di riempimento; non è necessario perché le lunghezze codificate previste per le rispettive dimensioni intere decodificate sono fisse e note (rispettivamente 11 e 22 "cifre" codificate per 64 e 128 bit).

Con un'eccezione minore (discussa di seguito), i dettagli completi della mappatura Base64 possono essere dedotti da dati accessibili al pubblico. Con un minimo di congetture, è probabile che lo schema Base64 utilizzato nelle stringhe videoId e channelId sia il seguente:

    ——₀————₁————₂————₃————₄————₅————₆————₇————₈————₉———₁₀———₁₁———₁₂———₁₃———₁₄———₁₅—
     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    -    _

Il motivo per credere che Base64 sia utilizzato è che, quando assumiamo dimensioni intere standard di 64 e 128 bit per l'ingresso dell'encoder, Base64 prevede esattamente le lunghezze insolite dei caratteri (11 e 22 caratteri) degli identificatori ID e videoId di YouTube . Inoltre, i resti calcolati secondo Base64 spiegano perfettamente la variazione distributiva osservata trovata nel l̲a̲s̲t̲ c̲h̲a̲r̲a̲c̲t̲e̲r̲ di ciascun tipo di stringa identificativa. Segue la discussione di questi punti.

In entrambi i casi, i "dati" binari che vengono codificati in Base64 sono un singolo intero, 64 o 128 bit, per (rispettivamente) videoId vs. channelId . Di conseguenza, usando un decodificatore Base64, un singolo intero può essere recuperato dall'identificatore di stringa e può essere molto utile farlo perché, mentre ogni ID intero contiene esattamente le stesse informazioni della stringa Base64 e consente anche alla stringa di ricreabile in qualsiasi momento: rispetto alle stringhe Base64 memorizzate come Unicode, la rappresentazione binaria è più piccola del 63%, ha la massima densità di bit del 100%, si allinea meglio nella memoria, ordina e hash più velocemente e, forse soprattutto, elimina false collisioni tra identificatori che differiscono solo nel caso ortografico. Quest'ultimo problema, sebbene estremamente improbabile numericamente, non può tuttavia essere escluso quando gli ID Base64 sono considerati insensibili al maiuscolo / minuscolo, come fanno alcuni file system (ad esempio Windows , risalenti a DOS ).

È un po 'importante: se stai usando una stringa videoId / channelId come parte di un nome di file Windows / NTFS, c'è una minuscola minuscola - ma comunque diversa da zero - la possibilità di collisioni di nomi di file dovute a quei filesystem che distribuiscono percorsi e nomi dei file senza distinzione tra maiuscole e minuscole .

Se sei preoccupato per questo possibile problema remoto, un modo per eliminarlo matematicamente sarebbe ricodificare gli interi decodificati - ancora ottenuti come descritto in questo articolo - in base-10 (decimale) o (uniforme- cased) rappresentazione esadecimale, per l'uso in percorsi o nomi di file su tali filesystem. [nota 2.] In questo approccio, l' Id video a 64 bit avrebbe bisogno di 20 cifre decimali [0-9]o 8 cifre esadecimali [0-9,A-F]( rispetto a 11 cifre Base64). L' ID canale a 128 bit richiederebbe un massimo di 39 cifre decimali o 16 cifre esadecimali ( rispetto a 22 cifre Base64).

La decodifica in binario è banale per il caso a 64 bit perché è possibile utilizzare un UInt64( ulongin C # ) per contenere il valore binario nativo che ritorna.

/// <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 = { "", "==", "=" };

Nel caso dei valori a 128 bit , è leggermente più complicato perché, a meno che il compilatore non abbia una __int128rappresentazione, dovrai trovare un modo per archiviare tutto e mantenerlo combinato mentre lo fai passare. Un tipo di valore semplice (o System.Numerics.Vectors.Vector<T>, che si manifesta come un registro hardware SIMD a 128 bit, quando disponibile) farà il trucco in .NET (non mostrato).

[ modifica: ]
Dopo ulteriori riflessioni, una parte del mio post originale non è stata completata al massimo. Per correttezza, viene mantenuto il brano originale (è possibile saltarlo se lo si desidera); immediatamente sotto spiego l'intuizione mancante:

[ original: ]
Avrai notato in precedenza che ho scritto che puoi recuperare un "intero". Non sarebbe questo il valore originariamente codificato? Non necessariamente. E non sto alludendo alla distinzione firmata / non firmata che, è vero, non può essere accertata qui (perché non cambia alcun dato sull'immagine binaria). Sono i valori numerici stessi: senza un po 'di " Rosetta Stone"che ci permetterebbe di fare un controllo incrociato con valori assoluti noti come" corretti ", la mappatura alfabetica numerica e anche l'endianità non possono essere conosciute positivamente, il che significa che non c'è garanzia che tu stia recuperando lo stesso valore che codificato dai computer di YouTube. Fortunatamente, fintanto che YouTube non espone pubblicamente i cosiddetti valori corretti in un formato meno opaco da qualche altra parte, questo non può avere importanza.

Questo perché i valori decodificati a 64 o 128 bit non sono utili se non come token identificativo, quindi i nostri unici requisiti per la trasformazione sono la codifica distinta (non si scontrano due token univoci) e la reversibilità (la decodifica recupera l'identità del token originale).

In altre parole, tutto ciò che ci interessa davvero è il round-tripless lossless della stringa Base64 originale. Poiché Base64 è senza perdita di dati e reversibile (purché si attenga sempre alla stessa mappatura alfabetica e presupposto di endianness sia per la codifica che per la decodifica), soddisfa i nostri scopi. I tuoi valori numerici potrebbero non corrispondere a quelli registrati nel master vault di YouTube, ma non sarai in grado di dire alcuna differenza.


[ nuova analisi: ]
Si scopre che ci sono alcuni indizi che possono parlarci della "vera" mappatura Base64 . Solo alcune mappature prevedono i caratteri della posizione finale che osserviamo, il che significa che il valore binario solo per quei caratteri deve avere un certo numero di zeri LSB. Eh.

Considerato il presupposto estremamente probabile che i caratteri alfabetici e numerici siano mappati in ordine crescente, possiamo sostanzialmente confermare che la mappatura è quella mostrata nelle tabelle sopra. L'unica incertezza residua su cui l'analisi LSB è inconcludente è il possibile scambio dei caratteri -e _( 62/ 63).

Il testo originale ha fatto discutere di questo problema LSB (vedi più avanti), ma quello che non mi rendo perfettamente conto, al momento è stato come LSB informazioni atti a limitare le possibili Base64 mappature.

Un ultimo commento su questo è che potresti effettivamente voler intenzionalmente scegliere il big-endian per l'interpretazione binaria con cui la tua app lavora internamente (anche se è meno comune del little-endian al giorno d'oggi e quindi potrebbe non essere il modo in cui YouTube "ufficialmente" fa esso). Il motivo è che questo è un caso di doppia vista sullo stesso valore, in modo tale che l'ordine di byte effettivo sia visibilmente esposto nella rappresentazione Base64. È utile e meno confuso mantenere l' ordinamento coerente tra il valore binario e la stringa Base64 (un po 'più) leggibile dall'uomo, ma il tipo di valori binari little-endian è una confusione non banale dell'ordinamento ASCII / lessicale desiderato .

Non esiste una soluzione semplice per questo problema se inizi con valori ID little-endian (vale a dire che semplicemente invertire il loro ordinamento non funzionerà). Invece, devi pianificare in anticipo e invertire i byte di ciascun valore binario al momento della decodifica . Quindi, se ti preoccupi della visualizzazione alfabetica corrispondente all'ordinamento dei valori binari, potresti voler modificare la funzione mostrata sopra in modo che decodifichi in valori big-endian ulong . Ecco quel codice:

// 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 YouTube


ID video

Per il videoId , è un numero intero a 8 byte (64 bit). L'applicazione della codifica Base64 a 8 byte di dati richiede 11 caratteri . Tuttavia, poiché ogni carattere Base64 trasmette esattamente 6 bit (vale a dire, 2⁶ equivale a 64), questa allocazione potrebbe effettivamente contenere fino a 11 × 6 = 66bit, un surplus di 2 bit rispetto ai 64 bit necessari per il nostro payload. I bit in eccesso sono impostati su zero, il che ha l'effetto di escludere alcuni caratteri dall'apparire mai nell'ultima posizione della stringa codificata. In particolare, il videoId è garantito per finire sempre con uno dei seguenti caratteri:

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

Pertanto, l'espressione regolare con il limite massimo (RegEx) per il videoId sarebbe la seguente:

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


ID canale o playlist

Le stringhe channelId e playlistId sono prodotte dalla codifica Base64 di un intero binario a 128 bit (16 byte). Ciò fornisce una stringa di 22 caratteri che può essere preceduta o UCper identificare il canale stesso o UUper identificare una playlist completa dei video che contiene. Queste stringhe con prefisso di 24 caratteri vengono utilizzate negli URL . Ad esempio, quanto segue mostra due modi per fare riferimento allo stesso canale. Si noti che la versione della playlist mostra il numero totale di video nel canale, [vedi nota 3.] un'informazione utile che le pagine del canale non espongono.

URL del canale
https://www.youtube.com/channel/UC K8sQmJBp8GCxrOtXWBpyEA
URL playlist
https://www.youtube.com/playlist?list=UU K8sQmJBp8GCxrOtXWBpyEA

Come nel caso dell'Id video a 11 caratteri , il calcolo per Base64 prevede correttamente la lunghezza della stringa osservata di 22 caratteri . In questo caso, l'output è in grado di codificare 22 × 6 = 132bit, un surplus di 4 bit; quegli zeri finiscono per limitare la visualizzazione di m̲o̲s̲t̲ dei 64 simboli alfabetici nell'ultima posizione, con solo 4 rimanenti idonei. Pertanto, sappiamo che l'ultimo carattere in una stringa ID canale YouTube deve essere uno dei seguenti:

{ A, Q, g, w }

Questo ci dà l'espressione regolare strettamente vincolata per un channelId :

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

Come nota finale, le espressioni regolari mostrate sopra descrivono solo i valori di ID nudo, senza prefissi, barre, separatori, ecc., Che devono essere presenti negli URL e negli altri vari usi. I pattern RegEx che ho presentato sono matematicamente il più minimali possibile date le proprietà delle stringhe degli identificatori, ma se usati così come sono senza contesto aggiuntivo probabilmente genereranno molti falsi positivi, cioè: abbinano erroneamente il testo spurio. Per evitare questo problema nell'uso effettivo, circondali con il maggior numero possibile di contesti adiacenti previsti.


Note

[1.]
Come promesso sopra, ecco un estratto dalla specifica Base64 che discute le loro considerazioni nella selezione dei simboli alfabetici. Le persone che cercano di capire come il processo si è concluso nella selezione dei caratteri con la semantica dell'URL possono trovare le spiegazioni in qualche modo non edificanti.

3.4. La scelta dell'alfabeto

Applicazioni diverse hanno requisiti diversi sui caratteri dell'alfabeto. Ecco alcuni requisiti che determinano quale alfabeto deve essere usato:

  • Gestito dagli umani. I caratteri "0" e "O" sono facilmente confusi, così come "1", "l" e "I". Nell'alfabeto base32 di seguito, dove 0 (zero) e 1 (uno) non sono presenti, un decodificatore può interpretare 0 come O e 1 come I o L a seconda del caso. (Tuttavia, per impostazione predefinita non dovrebbe; vedere la sezione precedente.)

  • Codificato in strutture che impongono altri requisiti. Per la base 16 e la base 32, questo determina l'uso di alfabeti maiuscoli o minuscoli. Per la base 64, i caratteri non alfanumerici (in particolare "/") possono essere problematici nei nomi di file e negli URL.

  • Utilizzato come identificatore. Alcuni caratteri, in particolare "+" e "/" nell'alfabeto base 64, sono trattati come interruzioni di parole dagli strumenti di ricerca / indice del testo legacy.

Non esiste un alfabeto universalmente accettato che soddisfi tutti i requisiti. Per un esempio di variante altamente specializzata, vedi IMAP [8]. In questo documento, documentiamo e denominiamo alcuni alfabeti attualmente utilizzati.

[2.]
In alternativa, per risolvere il problema dell'uso di stringhe di ID con codifica Base64 come componenti "così come sono" di nomi di file o percorsi sul filesystem NTFS, che non distingue tra maiuscole e minuscole per impostazione predefinita (e quindi tecnicamente rischia di confondere uno o più valori ID non correlati), è possibile che NTFS possa essere configurato con nomi di file / percorsi con distinzione tra maiuscole e minuscole in base al volume. L'abilitazione del comportamento non predefinito può risolvere il problema qui descritto, ma raramente è raccomandato poiché altera le aspettative per qualsiasi / tutte le diverse applicazioni che ispezionano o accedono al volume. Se stai anche considerando questa opzione, leggi e capisci prima questo , e probabilmente cambierai idea.

[3.]
Credo che il numero totale di video mostrati nella pagina della playlist del canale tenga conto di un'esclusione per i video che sono limitati in base alla regione geografica del client HTTP. Ciò spiega eventuali discrepanze tra il numero di video elencati per la playlist e il canale.


3
Questo è un lavoro investigativo impressionante.
Ale

3
Santo guacamole, questa risposta merita migliaia di voti
pilau,

Gli ID canale YouTube sono ora lunghi 24 caratteri, non 22; ad es. UCjXfkj5iapKHJrhYfAF9ZGg; fonte: stackoverflow.com/questions/14366648/...
evandrix

1
@evandrix Grazie per la tua nota. L'ultimo paragrafo del mio post era destinato a risolvere questo problema; Discuto solo la parte variabile della stringa ID. Esistono prefissi per l'ID canale (può essere ad esempio UC o UU ) che non sono discussi in questo post. Se hai un valore prefissato come il tuo esempio, le informazioni che fornisco si applicano agli ultimi 22 caratteri.
Glenn Slayden,

1
@evandrix Se sei ancora interessato, ho appena aggiornato l'articolo stesso per includere informazioni sui prefissi UC vs. UU channelId .
Glenn Slayden,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.