Формат для ідентифікатора відео YouTube


32

Кожне відео YouTube має унікальний ідентифікатор, за допомогою якого можна отримати його. Наприклад, відео на сайті http://www.youtube.com/watch?v=aN46pEO_jX8має ідентифікатор aN46pEO_jX8.

Після деякого спостереження мені здається, що ці посвідчення особи дотримуються наступних двох правил:

  • Рівно 11 символів
  • Дозволені символи: az, AZ, 0-9, - і _

Я хочу знати:

  1. Чи завжди ці два правила завжди правильні.
  2. Якщо є якісь інші правила, які важливо дотримуватися.

Відповіді:


38

Згідно з документацією Youtube 2.0 API та документацією 3.0 API , videoId - це рядок, нічого не вказано про поточний набір символів, що використовуються ...

Про довжину 11 символів у публікації команди API API YouTube :

Я не бачу ніде в документації, де ми офіційно зобов'язуємося до стандартної довжини 11 символів для відео-ідентифікаторів YouTube. Це одна з тих речей, де ми маємо поточну реалізацію, і вона може залишатися такою нескінченно. Але ми не пропонуємо жодних офіційних зобов’язань щодо цього, тому дійте на свій страх і ризик.

І останнє, але не менш важливе, ще одна публікація уточнює (чи ні) формат:

Ми не надаємо жодних публічних гарантій щодо формату відеодокументів. Хоча вони наразі мають 11 символьних рядків, що містять літери, цифри та деякі розділові знаки, я б не рекомендував жорстке кодування у вашій програмі (якщо ви не маєте легкого способу змінити її в майбутньому).

Здається, команда Youtube вважає за краще безпосередньо запитати сервер Youtube, чи правильно Video_ID чи ні (див. Існуюче відео):

Якщо вам потрібно перевірити, що випадковий вхід користувача відповідає дійсному ідентифікатору відео, я рекомендую зробити емпіричний тест. Спроба доступу

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

Якщо ви отримаєте відповідь 200, то VIDEO_ID дійсний. Якщо ви отримали відповідь не 200, у вас є недійсний ідентифікатор. Є кілька кращих випадків для нещодавно завантажених відео чи приватних відео, але для більшості цілей я б припускав, що це буде добре.


Це чудова відповідь і дав мені всю необхідну мені інформацію! Дякую!
асфальти

3
Після цього повертається HTTP 410, який вже не було. Будь-які ідеї щодо нової URL-адреси, щоб перевірити це зараз?
Буде Строль

1
Щоб перевірити відео-ідентифікатор: просто отримайте HTML-сторінку з YouTube та переконайтеся, що мета-канонічне посилання має той самий ідентифікатор, який ви вказали.
пучу

50

YouTube- ідентифікатори videoId та channelId - це єдині цілі значення, представлені у дещо зміненій версії кодування 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 не використовують =символ прокладки; це не обов'язково, оскільки кодовані довжини, що очікуються на відповідний розшифрований цілий розмір, є фіксованими та відомими (11 та 22 закодовані 'цифри' для 64 та 128 біт відповідно).

За одним незначним винятком (обговорюється нижче), повні деталі відображення Base64 можна отримати з загальнодоступних даних. З мінімумом здогадок, ймовірно, що схема Base64 , що використовується у рядках videoId та channelId, є наступною:

    ——₀————₁————₂————₃————₄————₅————₆————₇————₈————₉———₁₀———₁₁———₁₂———₁₃———₁₄———₁₅—
     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 точно прогнозує незвичайні довжини символів (11 та 22 символи) для YouTube- ідентифікаторів YouTubeId та videoId . Крім того, залишки, розраховані за Base64, прекрасно пояснюють спостережувані зміни розподілу, знайдені в l̲a̲s̲t̲ c̲h̲a̲r̲a̲c̲t̲e̲r̲ кожного типу ідентифікаційного рядка. Далі йде обговорення цих питань.

В обох випадках двійкові «дані», які отримують кодовані Base64, є єдиним цілим числом, або 64, або 128 бітами, для (відповідно) videoId проти channelId . Відповідно, за допомогою декодера Base64, одне ціле число може бути відновлено з ідентифікатора рядка, і це може бути досить корисно, оскільки, хоча кожен цілий ідентифікатор містить точно таку ж інформацію, як і рядок Base64, а також дозволяє рядку відтворювати в будь-який час - у порівнянні з рядками Base64, що зберігаються як Unicode, бінарне представлення на 63% менше, має максимальну щільність бітів 100%, краще вирівнює пам’ять, сортує та зберігає швидше, і, що, головне, усуває помилкові зіткнення між ідентифікаторами, які відрізняються лише в ортографічному випадку. Ця остання проблема, хоча чисельно вкрай неможлива, проте не може бути виключена, коли ідентифікатори Base64 трактуються як нечутливі до регістру, як це роблять деякі файлові системи (наприклад, Windows , починаючи з DOS ).

Це якось важливо: якщо ви використовуєте рядок videoId / channelId як частину імені файлів Windows / NTFS, існує суттєва мінливість, але, тим не менш, нульова - зміна зіткнень імен файлів завдяки тим файловим системам, що розгортають шлях, нечутливий до регістру і іменування файлів. .

Якщо ви турбуєтесь про цю віддалену можливу проблему, одним із способів математичного усунення було б перекодування декодованих цілих чисел - як і раніше отриманих, як описано в цій статті - або в базову-10 (десяткову), або (рівномірну- cased) шістнадцяткове представлення, для використання у назвах шляхів або файлів у таких файлових системах. [Примітка 2.] У такому підході 64-розрядному videoId потрібно 20 знаків після коми [0-9]або 8 шістнадцяткових цифр [0-9,A-F]( проти 11 цифр Base64). Для 128-розрядного каналу IDI потрібно максимум 39 десяткових чи 16-ти шістнадцяткових цифр ( проти 22-х цифр Base64).

Розшифровка до двійкового файлу є тривіальною для 64-розрядного випадку, оскільки ви можете використовувати UInt64( ulongу C # ) для утримання нативного бінарного значення, яке повертається.

/// <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 (не показано).

[ ред .: ]
Після подальшої думки частина моєї оригінальної публікації була не максимально повною. Для справедливості зберігається оригінальний уривок (ви можете пропустити його за бажанням); одразу нижче я пояснюю пропущене розуміння:

[ Оригінал: ]
Ви , можливо, помітили вище , що я написав , що ви можете відновити « в » загалом. Чи не це було б значення, яке було спочатку закодовано? Не обов'язково. І я не натякаю на підписане / непідписане розрізнення, яке, правда, тут неможливо встановити (оскільки це не змінює жодних фактів про двійкове зображення). Це самі числові значення: Без якогось " Розетт-каменю""це дозволило б перехресно перевірити абсолютні значення, відомі як" правильні ", чисельне відображення алфавіту, а також ендіанство не може бути позитивно відомим, це означає, що немає гарантії, що ви відновите те саме значення, яке на щастя, доки YouTube ніколи не публічно не виставляє так званих правильних значень у менш непрозорому форматі десь в іншому місці, це, можливо, не має значення.

Це тому, що декодовані 64- або 128-бітні значення в будь-якому разі не використовуються, окрім як маркер ідентифікації, тому єдиними нашими вимогами до перетворення є чітке кодування (не стикаються два унікальних лексеми) та оборотність (декодування відновлює оригінальну тотожність токена).

Іншими словами, все, що нас насправді хвилює, - це збиток без втрат оригінального рядка Base64. Оскільки Base64 без втрат і оборотності (якщо ви завжди дотримуєтесь одного і того ж відображення алфавіту та припущення про витривалість як для кодування, так і для декодування), це відповідає нашим цілям. Ваші числові значення можуть не збігатися з тими, які записані в основній сховищі YouTube, але ви не зможете визначити різницю.


[ новий аналіз: ]
Виявляється, є кілька підказок, які можуть розповісти нам про "справжнє" відображення Base64 . Лише певні відображення передбачають символи кінцевої позиції, які ми спостерігаємо, тобто бінарне значення лише для цих символів повинно мати певну кількість нулів LSB. Хе.

У сукупності з надзвичайно ймовірним припущенням, що алфавіт і цифри символи відображаються у порядку зростання, ми можемо в основному підтвердити відображення таким, як показано в таблицях вище. Єдина невизначеність, щодо якої LSB-аналіз не є переконливою, - це можливий підміна символів -та _( 62/ 63).

Оригінальний текст зробив обговорити це питання LSB (див нижче), але то , що я не в повній мірі реалізувати в той час було як LSB інформація діє , щоб обмежити можливе Base64 відображення.

Останній коментар з цього приводу полягає в тому, що ви насправді можете навмисно вибрати big-endian для бінарної інтерпретації, з якою працює ваш додаток всередині (хоча це є менш поширеним, ніж сьогодні мало-ендіанський, і, таким чином, може бути не так, як YouTube "офіційно" робить це). Причина полягає в тому, що це випадок подвійних поглядів на одне і те ж значення, таким чином, що фактичний порядок байт помітно піддається викладу Base64. Це корисно і менш заплутано для того, щоб дотримуватися порядку сортування між бінарним значенням та (дещо більше) читаною людиною рядком Base64, але такий тип бінарних значень маленького ендіану - це нетривіальна кодифікація потрібного ASCII / лексичного сорту .

Виправити цю проблему не існує простого виправлення, якщо ви почнете зі значень ідентифікаторів малої кількості (тобто просто змінити їх вид не буде працювати). Натомість вам потрібно планувати заздалегідь і повертати байти кожного бінарного значення під час декодування . Тож якщо ви дбаєте про те, щоб алфавітний дисплей відповідав сортуванням двійкових значень, ви можете змінити функцію, показану вище, щоб вона замість цього була розшифрована у великі-ендіанські 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


Ідентифікатор відео

Для videoId це 8-байтове (64-бітове) ціле число. Застосування кодування Base64 до 8 байт даних вимагає 11 символів . Однак, оскільки кожен символ Base64 передає рівно 6 біт (а саме 2⁶ дорівнює 64), це розподіл може насправді містити до 11 × 6 = 66бітів - надлишок у 2 біти над 64 бітами, що потребує нашого корисного навантаження. Зайві біти встановлені в нуль, що призводить до того, що певні символи ніколи не з'являться в останньому положенні закодованого рядка. Зокрема, відеоідентифікатор гарантовано завжди закінчується одним із наступних символів:

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

Таким чином, максимально обмежений регулярний вираз (RegEx) для videoId буде таким:

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


Ідентифікатор каналу чи списку відтворення

Рядок ChannelId та playlistId виробляються Base64-кодуванням 128-бітового (16-байтового) двійкового цілого числа. Це дає 22-символьний рядок, який можна встановити як UCдля ідентифікації самого каналу, так і UUдля ідентифікації повного списку відтворення відео, який він містить. Ці строчки з 24 символами використовуються в URL-адресах . Наприклад, нижче показано два способи посилання на один і той же канал. Зауважте, що версія списку відтворення показує загальну кількість відео на каналі [див. Примітку 3.] корисну інформацію, яку сторінки каналу не відкривають.

URL-адреса каналу
https://www.youtube.com/channel/UC K8sQmJBp8GCxrOtXWBpyEA
URL-адреса списку відтворення
https://www.youtube.com/playlist?list=UU K8sQmJBp8GCxrOtXWBpyEA

Як і у випадку з 11-символьним videoId , обчислення на Base64 правильно прогнозує спостережувану довжину рядка в 22 символи . У цьому випадку вихід здатний кодувати 22 × 6 = 132біти, надлишок 4 біт; ці нулі в кінцевому підсумку обмежують показ m̲o̲s̲t̲ з 64 символів алфавіту в останньому місці, при цьому залишаються лише 4. Тому ми знаємо, що останній символ у рядку каналуId YouTube повинен бути одним із наступних:

{ A, Q, g, w }

Це дає нам максимально обмежений регулярний вираз для channelId :

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

На завершення, регулярні вирази, показані вище, описують лише голові значення ідентифікатора, без префіксів, косої риси, роздільника тощо, які повинні бути присутніми в 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 як "як є" компоненти імен файлів або шляхів у файловій системі NTFS, яка за замовчуванням нечутлива до регістру (і, таким чином, технічно ризикує збити один чи більше непов'язані значення ідентифікатора), так буває, що NTFS можна налаштувати з урахуванням регістру іменування шляху / файлу на основі томів. Увімкнення поведінки, що не використовується за замовчуванням, може виправити описану тут проблему, але її рідко рекомендується, оскільки вона змінює очікування для будь-яких / всіх розрізнених програм, які перевіряють або отримують доступ до тома. Якщо ви навіть розглядаєте цей варіант, прочитайте і зрозумійте це спочатку, і ви, мабуть, передумаєте.

[3.]
Я вважаю, що загальна кількість відео, показаних на сторінці відтворення каналу, враховує виключення для відео, які обмежені відповідно до географічного регіону клієнта HTTP. Це пояснює будь-яку невідповідність між кількістю перелічених відео для списку відтворення та каналу.


3
Це якась вражаюча детективна робота.
але

3
Святий гуакамоле, це відповідає заслуговує 1,000s з upvotes
плов

Тепер ідентифікатори каналів YouTube становлять 24 символи, а не 22; наприклад, UCjXfkj5iapKHJrhYfAF9ZGg; Джерело: stackoverflow.com/questions/14366648 / ...
evandrix

1
@evandrix Дякуємо за вашу замітку. Останній абзац мого поста був призначений для вирішення цього питання; Я обговорюю лише змінну частину рядка ID. Існують префікси для ідентифікатора каналу (можуть бути, наприклад, UC або UU ), які не обговорюються в цій публікації. Якщо у вас є префіксне значення, наприклад ваш приклад, інформація, яку я пропоную, стосується останніх 22 символів.
Гленн Слейден

1
@evandrix У разі , якщо ви все ще цікаво, я просто оновив саму статтю , щоб включити інформацію про UC проти UU channelId префіксів.
Гленн Слейден
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.