Apakah mungkin menggunakan RegEx untuk memvalidasi, atau membersihkan data Base64? Itu pertanyaan sederhana, tetapi faktor yang mendorong pertanyaan ini adalah yang membuatnya sulit.
Saya memiliki decoder Base64 yang tidak dapat sepenuhnya mengandalkan data input untuk mengikuti spesifikasi RFC. Jadi, masalah yang saya hadapi adalah masalah seperti mungkin data Base64 yang mungkin tidak dipecah menjadi 78 (menurut saya 78, saya harus memeriksa ulang RFC, jadi jangan tanya saya jika nomor pastinya salah) karakter garis, atau garis mungkin tidak diakhiri dengan CRLF; dalam hal ini mungkin hanya CR, atau LF, atau mungkin tidak keduanya.
Jadi, saya mengalami kesulitan mengurai data Base64 yang diformat seperti itu. Karenanya, contoh seperti berikut menjadi tidak mungkin untuk didekode dengan andal. Saya hanya akan menampilkan header MIME parsial agar singkatnya.
Content-Transfer-Encoding: base64
VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu
Oke, jadi parsing itu tidak masalah, dan persis seperti hasil yang kita harapkan. Dan dalam 99% kasus, menggunakan kode apa pun untuk setidaknya memverifikasi bahwa setiap karakter dalam buffer adalah karakter base64 yang valid, berfungsi dengan sempurna. Tapi, contoh berikutnya melempar kunci pas ke dalam campuran.
Content-Transfer-Encoding: base64
http://www.stackoverflow.com
VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu
Ini adalah versi pengkodean Base64 yang telah saya lihat di beberapa virus dan hal-hal lain yang mencoba memanfaatkan keinginan pembaca email untuk mengurai pantomim dengan segala cara, versus yang hanya sesuai dengan buku, atau lebih tepatnya RFC; jika kamu mau.
Dekoder Base64 saya menerjemahkan contoh kedua ke aliran data berikut. Dan perlu diingat di sini, streaming aslinya adalah semua data ASCII!
[0x]86DB69FFFC30C2CB5A724A2F7AB7E5A307289951A1A5CC81A5CC81CDA5B5C1B19481054D0D
2524810985CD94D8D08199BDC8814DD1858DAD3DD995C999B1BDDC8195E1B585C1B194B8
Adakah yang punya cara bagus untuk menyelesaikan kedua masalah sekaligus? Saya tidak yakin itu bahkan mungkin, di luar melakukan dua transformasi pada data dengan aturan berbeda yang diterapkan, dan membandingkan hasilnya. Namun jika Anda mengambil pendekatan itu, keluaran mana yang Anda percayai? Tampaknya heuristik ASCII adalah tentang solusi terbaik , tetapi berapa banyak lagi kode, waktu eksekusi, dan kerumitan yang akan ditambahkan ke sesuatu yang serumit pemindai virus, di mana kode ini sebenarnya terlibat? Bagaimana Anda melatih mesin heuristik untuk mempelajari apa yang dapat diterima Base64, dan apa yang tidak?
MEMPERBARUI:
Lakukan terhadap jumlah tampilan yang terus didapat pertanyaan ini, saya telah memutuskan untuk memposting RegEx sederhana yang telah saya gunakan dalam aplikasi C # selama 3 tahun sekarang, dengan ratusan ribu transaksi. Jujur, saya paling suka jawaban yang diberikan oleh Gumbo , itulah mengapa saya memilihnya sebagai jawaban terpilih. Tetapi bagi siapa pun yang menggunakan C #, dan mencari cara yang sangat cepat untuk setidaknya mendeteksi apakah sebuah string, atau byte [] berisi data Base64 yang valid atau tidak, saya telah menemukan yang berikut ini bekerja dengan sangat baik untuk saya.
[^-A-Za-z0-9+/=]|=[^=]|={3,}$
Dan ya, ini hanya untuk STRING data Base64, BUKAN pesan RFC1341 yang diformat dengan benar . Jadi, jika Anda berurusan dengan data jenis ini, harap pertimbangkan itu sebelum mencoba menggunakan RegEx di atas. Jika Anda berurusan dengan Base16, Base32, Radix atau bahkan Base64 untuk tujuan lain (URL, nama file, Pengkodean XML, dll.), Maka itu adalah sangat disarankan agar Anda membaca RFC4648 yang disebutkan Gumbo dalam jawabannya karena Anda perlu melakukannya dengan baik mengetahui charset dan terminator yang digunakan oleh implementasi sebelum mencoba menggunakan saran dalam set pertanyaan / jawaban ini.
sumber
^
luar tanda kurung, sebagai jangkar-awal. Namun, regex yang jauh lebih baik, tanpa serumit jawaban yang diterima, adalah^[-A-Za-z0-9+/]*={0,3}$
Jawaban:
Dari RFC 4648 :
Jadi itu tergantung pada tujuan penggunaan data yang disandikan jika data tersebut dianggap berbahaya.
Namun jika Anda hanya mencari ekspresi reguler untuk mencocokkan kata-kata yang dikodekan Base64, Anda dapat menggunakan yang berikut ini:
sumber
name
adalah pengkodean Base64 valid dari urutan byte (hex)9d a9 9e
.^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$
harus menghindari serangan balikYang ini bagus, tetapi akan cocok dengan String kosong
Yang ini tidak cocok dengan string kosong:
sumber
MQ==
tidak cocok dengan ekspresi AndaAQENVg688MSGlEgdOJpjIUC=
adalah formulir yang valid.=
. Yang terakhir?
memungkinkan untuk 0=
. Menggantinya dengan{1}
membutuhkan 1 atau 2 ending=
Baik " : " maupun " . " Tidak akan muncul di Base64 yang valid, jadi menurut saya Anda dapat membuang
http://www.stackoverflow.com
garis secara jelas. Di Perl, katakanlah, sesuatu sepertimungkin yang Anda inginkan. Itu menghasilkan
Ini adalah ASCII Base64 sederhana untuk contoh StackOverflow.
sumber
Regexp terbaik yang dapat saya temukan hingga saat ini ada di sini https://www.npmjs.com/package/base64-regex
yang di versi saat ini terlihat seperti:
sumber
\\n?
.Untuk memvalidasi gambar base64 kita bisa menggunakan regex ini
sumber