YouTube VideoId dan ID Saluran pengidentifikasi adalah nilai-nilai bilangan bulat diwakili dalam versi modifikasi dari Base64 encoding . Satu perbedaan versus rekomendasi IETF RFC4648 adalah penggantian dua karakter dalam abjad penyandian:
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)
Substitusi kemungkinan karena fakta bahwa, karena alasan tertentu RFC4648 memilih dua karakter yang sudah memiliki fungsi yang menonjol dan mapan dalam URL. [Catatan 1.] Jelas, untuk penggunaan yang sedang dibahas di sini, komplikasi tertentu sebaiknya dihindari.
Perbedaan lain dari spesifikasi resmi adalah bahwa pengidentifikasi YouTube tidak menggunakan =
karakter padding; itu tidak perlu karena panjang yang dikodekan diharapkan per ukuran bilangan bulat yang didekodekan masing-masing adalah tetap dan diketahui (11 dan 22 'digit' yang dikodekan untuk 64 dan 128 bit, masing-masing).
Dengan satu pengecualian kecil (dibahas di bawah), detail lengkap pemetaan Base64 dapat disimpulkan dari data yang dapat diakses publik. Dengan minimal menebak, kemungkinan bahwa Base64 skema yang digunakan dalam VideoId dan ID Saluran string adalah sebagai berikut:
——₀————₁————₂————₃————₄————₅————₆————₇————₈————₉———₁₀———₁₁———₁₂———₁₃———₁₄———₁₅—
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 - _
Alasan untuk percaya bahwa Base64 sedang digunakan adalah bahwa, ketika kita mengasumsikan ukuran integer standar 64 dan 128 bit untuk input encoder, Base64 memprediksi panjang karakter yang tidak biasa (11 dan 22 karakter) dari channelId dan videoId pengidentifikasi YouTube persis. Selanjutnya, sisa dihitung sesuai Base64 dengan sempurna menjelaskan variasi distribusi yang diamati ditemukan di l̲a̲s̲t̲ c̲h̲a̲r̲a̲c̲t̲e̲r̲ dari setiap jenis string pengidentifikasi. Pembahasan poin-poin ini berikut.
Dalam kedua kasus, "data" biner yang mendapatkan encoded Base64 adalah integer tunggal, baik 64 atau 128 bit, untuk (masing-masing) videoId vs channelId . Dengan demikian, dengan menggunakan decoder Base64, satu integer dapat dipulihkan dari pengidentifikasi string, dan itu bisa sangat berguna untuk melakukan ini karena, sementara setiap id integer berisi informasi yang persis sama dengan string Base64 — dan juga memungkinkan string untuk dibuat ulang kapan saja — bila dibandingkan dengan string Base64 yang disimpan sebagai Unicode, representasi biner 63% lebih kecil, memiliki kerapatan bit maksimal 100%, menyelaraskan dalam memori lebih baik, memilah dan memilah lebih cepat, dan, mungkin yang paling penting, menghilangkan tabrakan palsu antara pengidentifikasi yang hanya berbeda dalam kasus ortografi. Masalah terakhir ini, meskipun sangat tidak mungkin secara numerik, namun tidak dapat dikesampingkan ketika Base64 ID diperlakukan sebagai tidak peka huruf besar kecil, seperti yang dilakukan oleh beberapa sistem file (misalnya Windows , sejak DOS ).
Itu agak penting: jika Anda menggunakan VideoId / ID Saluran string sebagai bagian dari nama file / Windows NTFS, ada vanishingly miniscule tapi tetap non zero- -chance tabrakan nama file karena mereka filesystem menyebarkan case-sensitive jalan dan pemberian nama file .
Jika Anda khawatir tentang masalah yang mungkin terjadi dari jarak jauh ini, salah satu cara untuk menghilangkannya secara matematis adalah dengan mengkode ulang bilangan bulat yang didekodekan - masih diperoleh seperti yang dijelaskan dalam artikel ini - menjadi basis-10 (desimal) atau (seragam- cased) representasi heksadesimal, untuk digunakan dalam path atau nama file pada sistem file tersebut. [note 2.] Dalam pendekatan ini, videoId 64-bit akan membutuhkan 20 digit desimal [0-9]
atau 8 digit hex [0-9,A-F]
( vs 11 digit Base64). ChannelId 128-bit akan membutuhkan maksimum 39 digit desimal atau 16 digit hex ( vs 22 digit Base64).
Mendekode ke biner adalah sepele untuk kasus 64-bit karena Anda dapat menggunakan UInt64
( ulong
dalam C # ) untuk menyimpan nilai biner asli yang kembali.
/// <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 = { "", "==", "=" };
Untuk kasus nilai 128-bit , ini sedikit lebih sulit karena, kecuali jika kompiler Anda memiliki __int128
representasi, Anda harus mencari cara untuk menyimpan semuanya dan tetap mengkombinasikannya saat Anda menyebarkannya. Jenis nilai sederhana (atau System.Numerics.Vectors.Vector<T>
, yang bermanifestasi sebagai register perangkat keras SIMD 128-bit, bila tersedia) akan melakukan trik dalam .NET (tidak ditampilkan).
[ Sunting: ]
Setelah berpikir lebih lanjut, sebagian dari posting asli saya tidak lengkap secara maksimal. Demi keadilan, kutipan aslinya dipertahankan (Anda bisa melewatkannya jika diinginkan); tepat di bawah ini saya jelaskan wawasan yang hilang:
[ asli: ]
Anda mungkin telah memperhatikan di atas bahwa saya menulis bahwa Anda dapat memulihkan bilangan bulat " an ". Bukankah ini nilai yang semula dikodekan? Belum tentu. Dan saya tidak menyinggung perbedaan yang ditandatangani / tidak ditandatangani yang, memang benar, tidak dapat dipastikan di sini (karena tidak mengubah fakta tentang gambar biner). Ini nilai numerik sendiri: Tanpa beberapa " Rosetta Stone"Itu akan memungkinkan kami melakukan pengecekan silang dengan nilai absolut yang dikenal sebagai" benar ", pemetaan alfabet numerik dan juga endian-ness tidak dapat diketahui secara positif, yang berarti bahwa tidak ada jaminan bahwa Anda memulihkan nilai yang sama dengan komputer di YouTube dikodekan. Untungnya, selama YouTube tidak pernah secara terbuka mengekspos apa yang disebut nilai yang benar dalam format yang kurang buram di tempat lain, ini tidak mungkin menjadi masalah.
Itu karena nilai-nilai 64- atau 128-bit yang didekode tidak menggunakan kecuali sebagai token pengidentifikasi, jadi hanya persyaratan kami untuk transformasi adalah pengkodean yang berbeda (tidak ada dua token unik yang bertabrakan) dan reversibilitas (decoding memulihkan identitas token asli).
Dengan kata lain, yang benar-benar kita pedulikan adalah trip- lossing string Base64 yang asli. Karena Base64 bersifat lossless dan reversibel (selama Anda selalu berpegang pada pemetaan alfabet dan asumsi endianness yang sama untuk kedua encoding dan decoding) itu memenuhi tujuan kami. Nilai numerik Anda mungkin tidak cocok dengan yang dicatat di brankas utama YouTube, tetapi Anda tidak akan dapat membedakannya.
[ Analisis baru: ]
Ternyata ada yang beberapa petunjuk yang dapat memberitahu kita tentang "benar" Base64 pemetaan. Hanya pemetaan tertentu yang memprediksi karakter posisi akhir yang kami amati, artinya nilai biner untuk hanya karakter tersebut harus memiliki angka nol LSB tertentu. Heh.
Bersama-sama dengan asumsi yang sangat mungkin bahwa karakter alfabet dan digit dipetakan dalam urutan menaik, kita pada dasarnya dapat mengkonfirmasi pemetaan untuk menjadi apa yang ditunjukkan pada tabel di atas. Satu-satunya ketidakpastian yang tersisa di mana analisis LSB tidak dapat disimpulkan adalah kemungkinan pertukaran karakter -
dan _
( 62
/ 63
).
Teks asli memang membahas masalah LSB ini (lihat lebih lanjut di bawah), tetapi yang saya tidak sadari sepenuhnya pada saat itu adalah bagaimana informasi LSB bertindak untuk membatasi kemungkinan pemetaan Base64 .
Komentar terakhir tentang hal ini adalah bahwa Anda mungkin sebenarnya ingin secara sengaja memilih big-endian untuk interpretasi biner yang bekerja dengan aplikasi Anda secara internal (walaupun saat ini lebih jarang daripada little-endian saat ini dan dengan demikian mungkin tidak seperti yang dilakukan YouTube 'secara resmi'. saya t). Alasannya adalah bahwa ini adalah kasus tampilan ganda pada nilai yang sama, sehingga urutan byte sebenarnya terlihat di rendition Base64. Sangat membantu dan tidak membingungkan untuk menjaga urutan sortir konsisten antara nilai biner dan (agak lebih) string Base64 yang dapat dibaca manusia, tetapi jenis nilai biner little-endian adalah perebutan non-sepele dari ASCII / lexical sort yang diinginkan .
Tidak ada perbaikan sederhana untuk masalah ini jika Anda mulai dengan nilai ID little-endian (yaitu hanya membalik jenisnya tidak akan berhasil). Sebagai gantinya, Anda harus merencanakan ke depan dan membalikkan byte dari setiap nilai biner pada saat decoding . Jadi jika Anda peduli dengan tampilan alfabet yang cocok dengan pengurutan nilai-nilai biner, Anda mungkin ingin mengubah fungsi yang ditunjukkan di atas sehingga ia menerjemahkannya menjadi nilai big-endian ulong
sebagai gantinya. Inilah kode itu:
// 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
Untuk videoId , itu adalah integer 8-byte (64-bit). Menerapkan pengodean Base64 ke 8 byte data membutuhkan 11 karakter . Namun, karena setiap karakter Base64 menyampaikan tepat 6 bit (yaitu, 2⁶ sama dengan 64), alokasi ini sebenarnya bisa menampung hingga 11 × 6 = 66
bit — surplus 2 bit dari 64 bit yang dibutuhkan muatan kami. Bit berlebih disetel ke nol, yang memiliki efek mengecualikan karakter tertentu agar tidak pernah muncul di posisi terakhir string yang disandikan. Khususnya, videoId dijamin selalu berakhir dengan salah satu karakter berikut:
{ A, E, I, M, Q, U, Y, c, g, k, o, s, w, 0, 4, 8 }
Dengan demikian, ekspresi reguler dengan batasan maksimal (RegEx) untuk videoId adalah sebagai berikut:
[0-9A-Za-z_-]{10}[048AEIMQUYcgkosw]
Id Saluran atau Daftar Putar
The ID Saluran dan playlistId string yang diproduksi oleh Base64-encoding 128-bit (16-byte) bilangan bulat biner. Ini memberikan string 22 karakter yang dapat diawali dengan baik UC
untuk mengidentifikasi saluran itu sendiri, atau dengan UU
untuk mengidentifikasi daftar putar penuh dari video yang dikandungnya. String awalan 24 karakter ini digunakan dalam URL . Misalnya, berikut ini menunjukkan dua cara untuk merujuk ke saluran yang sama. Perhatikan bahwa versi daftar putar menunjukkan jumlah total video dalam saluran, [lihat catatan 3.] informasi penting yang tidak diungkapkan oleh halaman saluran.
URL saluranhttps://www.youtube.com/channel/UC K8sQmJBp8GCxrOtXWBpyEA
URL daftar putarhttps://www.youtube.com/playlist?list=UU K8sQmJBp8GCxrOtXWBpyEA
Seperti halnya dengan videoId 11-karakter , perhitungan per Base64 dengan benar memprediksi panjang string yang diamati dari 22-karakter . Dalam hal ini, output mampu mengkodekan 22 × 6 = 132
bit, surplus 4 bit; angka nol tersebut pada akhirnya membatasi m̲o̲s̲t̲ dari 64 simbol alfabet agar tidak muncul di posisi terakhir, dengan hanya 4 yang tersisa yang memenuhi syarat. Karena itu, kami tahu bahwa karakter terakhir dalam string YouTube channelId harus salah satu dari yang berikut:
{ A, Q, g, w }
Ini memberi kami ekspresi reguler yang dibatasi secara maksimal untuk channelId :
[0-9A-Za-z_-]{21}[AQgw]
Sebagai catatan akhir, ekspresi reguler yang ditunjukkan di atas hanya menjelaskan nilai ID telanjang, tanpa awalan, garis miring, pemisah, dll., Yang harus ada dalam URL dan berbagai penggunaan lainnya. Pola-pola RegEx yang saya sajikan seminimal mungkin secara matematis mengingat sifat-sifat string pengidentifikasi, tetapi jika digunakan apa adanya tanpa konteks tambahan, mereka mungkin akan menghasilkan banyak false-positif, yaitu: tidak cocok dengan teks palsu. Untuk menghindari masalah ini dalam penggunaan aktual, mengelilingi mereka dengan sebanyak mungkin konteks berdekatan yang diharapkan.
Catatan
[1.]
Seperti yang dijanjikan di atas, berikut adalah kutipan dari spesifikasi Base64 yang membahas pertimbangan mereka dalam memilih simbol alfabet. Individu yang ingin memahami bagaimana proses yang disimpulkan dalam pemilihan karakter dengan semantik URL dapat menemukan penjelasannya agak tidak membenarkan.
3.4. Memilih Alfabet
Aplikasi yang berbeda memiliki persyaratan berbeda pada karakter dalam alfabet. Berikut adalah beberapa persyaratan yang menentukan alfabet mana yang harus digunakan:
Ditangani oleh manusia. Karakter "0" dan "O" mudah bingung, seperti "1", "l", dan "I". Dalam alfabet base32 di bawah ini, di mana 0 (nol) dan 1 (satu) tidak ada, decoder dapat menafsirkan 0 sebagai O, dan 1 sebagai I atau L tergantung pada kasus. (Namun, secara default seharusnya tidak; lihat bagian sebelumnya.)
Dikodekan ke dalam struktur yang mengamanatkan persyaratan lain. Untuk basis 16 dan basis 32, ini menentukan penggunaan huruf besar atau kecil. Untuk base 64, karakter non-alfanumerik (khususnya, "/") mungkin bermasalah dalam nama file dan URL.
Digunakan sebagai pengidentifikasi. Karakter tertentu, terutama "+" dan "/" dalam alfabet dasar 64, diperlakukan sebagai kata-istirahat oleh alat pencarian / indeks teks warisan.
Tidak ada alfabet yang diterima secara universal yang memenuhi semua persyaratan. Untuk contoh varian yang sangat terspesialisasi, lihat IMAP [8]. Dalam dokumen ini, kami mendokumentasikan dan menamai beberapa huruf yang saat ini digunakan.
[2.]
Sebagai alternatif, untuk memecahkan masalah menggunakan string ID yang disandikan Base64 sebagai komponen "apa adanya" dari nama file atau jalur pada sistem file NTFS, yang secara case-insensitive secara default (dan dengan demikian secara teknis berisiko menyatukan satu atau lebih nilai ID yang tidak terkait), kebetulan NTFS dapat dikonfigurasikan dengan penamaan path / file case-sensitif berdasarkan volume per. Mengaktifkan perilaku non-default dapat memperbaiki masalah yang dijelaskan di sini, tetapi jarang direkomendasikan karena mengubah harapan untuk setiap / semua aplikasi berbeda yang memeriksa atau mengakses volume. Jika Anda bahkan mempertimbangkan opsi ini, baca dan pahami ini dulu, dan Anda mungkin akan berubah pikiran.
[3.]
Saya yakin jumlah total video yang diperlihatkan halaman daftar putar saluran memperhitungkan pengecualian untuk video yang dibatasi menurut wilayah geografis klien HTTP. Akun ini untuk setiap perbedaan antara jumlah video yang terdaftar untuk daftar putar vs saluran.