Apakah ada cara di C # untuk melihat apakah sebuah string dikodekan Base 64 selain hanya mencoba mengubahnya dan melihat apakah ada kesalahan? Saya memiliki kode kode seperti ini:
// Convert base64-encoded hash value into a byte array.
byte[] HashBytes = Convert.FromBase64String(Value);
Saya ingin menghindari pengecualian "Karakter tidak valid dalam string Base-64" yang terjadi jika nilainya bukan string base 64 yang valid. Saya hanya ingin memeriksa dan mengembalikan false daripada menangani pengecualian karena saya berharap terkadang nilai ini tidak akan menjadi string basis 64. Apakah ada cara untuk memeriksa sebelum menggunakan fungsi Convert.FromBase64String?
Terima kasih!
Pembaruan:
Terima kasih atas semua jawaban Anda. Berikut adalah metode ekstensi yang dapat Anda gunakan sejauh ini untuk memastikan string Anda akan melewati Convert.FromBase64String tanpa pengecualian. .NET tampaknya mengabaikan semua spasi tambahan dan akhir saat mengonversi ke basis 64 sehingga "1234" valid dan begitu juga "1234"
public static bool IsBase64String(this string s)
{
s = s.Trim();
return (s.Length % 4 == 0) && Regex.IsMatch(s, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None);
}
Bagi mereka yang bertanya-tanya tentang kinerja pengujian vs penangkapan dan pengecualian, dalam banyak kasus untuk 64 basis ini lebih cepat untuk memeriksa daripada menangkap pengecualian sampai Anda mencapai panjang tertentu. Semakin kecil panjangnya, semakin cepat
Dalam pengujian saya yang sangat tidak ilmiah: Untuk 10.000 iterasi untuk panjang karakter 100.000 - 110000, itu 2,7 kali lebih cepat untuk diuji terlebih dahulu.
Untuk 1000 iterasi untuk panjang karakter 1 - 16 karakter dengan total 16.000 tes, itu 10,9 kali lebih cepat.
Saya yakin ada titik di mana akan lebih baik untuk menguji dengan metode berbasis pengecualian. Saya hanya tidak tahu pada poin apa itu.
sumber
=
tanda. Jika padding salah, akan memberikan error meskipun inputnya cocok dengan ekspresi.\n\fLE16
- metode Anda akan menghasilkan positif palsu untuk ini. Untuk siapa saja yang membaca dan mencari metode yang sangat mudah; Saya akan merekomendasikan untuk menangkap FormatException atau menggunakan RegEx yang sesuai dengan spesifikasi, lihat stackoverflow.com/questions/475074/… .@"^[a-zA-Z0-9\+/]*={0,2}$"
Jawaban:
Sangat mudah untuk mengenali string Base64, karena hanya akan terdiri dari karakter
'A'..'Z', 'a'..'z', '0'..'9', '+', '/'
dan sering kali diisi di akhir hingga tiga '=', untuk membuat panjangnya kelipatan 4. Tetapi alih-alih membandingkan ini, Anda ' d lebih baik mengabaikan pengecualian, jika itu terjadi.sumber
Gunakan Convert.TryFromBase64String dari C # 7.2
sumber
Convert.TryFromBase64String(base64.PadRight(base64.Length / 4 * 4 + (base64.Length % 4 == 0 ? 0 : 4), '='), new Span<byte>(new byte[base64.Length]), out _)
. Terima kasih.Saya tahu Anda mengatakan Anda tidak ingin menangkap pengecualian. Tetapi, karena menangkap pengecualian lebih dapat diandalkan, saya akan melanjutkan dan memposting jawaban ini.
Pembaruan: Saya telah memperbarui kondisi berkat oybek untuk lebih meningkatkan keandalan.
sumber
base64String.Contains
beberapa kali dapat mengakibatkan kinerja yang burukbase64String
dalam hal string yang besar.base64String== null || base64String.Length == 0
denganstring.IsNullOrEmpty(base64String)
Saya yakin regex seharusnya:
Hanya mencocokkan satu atau dua tanda '=', bukan tiga.
s
harus menjadi string yang akan diperiksa.Regex
adalah bagian dariSystem.Text.RegularExpressions
namespace.sumber
Mengapa tidak menangkap pengecualian, dan mengembalikan False?
Ini untuk menghindari biaya tambahan dalam kasus umum.
sumber
Hanya demi kelengkapan saya ingin memberikan beberapa implementasi. Secara umum, Regex adalah pendekatan yang mahal, terutama jika stringnya besar (yang terjadi saat mentransfer file besar). Pendekatan berikut mencoba cara deteksi tercepat terlebih dahulu.
EDIT
Seperti yang disarankan oleh Sam , Anda juga dapat sedikit mengubah kode sumbernya. Dia memberikan pendekatan yang berkinerja lebih baik untuk langkah terakhir pengujian. Rutinitas
dapat digunakan untuk mengganti
if (!Base64Chars.Contains(value[i]))
baris denganif (IsInvalid(value[i]))
Kode sumber lengkap dengan peningkatan dari Sam akan terlihat seperti ini (komentar dihapus untuk kejelasan)
sumber
Jawabannya harus bergantung pada penggunaan string. Ada banyak string yang mungkin "valid base64" menurut sintaks yang disarankan oleh beberapa poster, tetapi mungkin "dengan benar" mendekode, tanpa kecuali, ke junk. Contoh: string 8char
Portland
adalah Base64 yang valid. Apa gunanya menyatakan bahwa ini adalah Base64 yang valid? Saya kira pada titik tertentu Anda ingin tahu bahwa string ini harus atau tidak boleh didekode Base64.Dalam kasus saya, saya memiliki string koneksi Oracle yang mungkin dalam teks biasa seperti:
atau di base64 seperti
Saya hanya perlu memeriksa keberadaan titik koma, karena itu membuktikan bahwa BUKAN base64, yang tentu saja lebih cepat daripada metode di atas.
sumber
Peraturan sepakbola tinggi Knibb!
Ini seharusnya relatif cepat dan akurat tetapi saya akui saya tidak mengujinya secara menyeluruh, hanya beberapa.
Ini menghindari pengecualian mahal, regex, dan juga menghindari perulangan melalui kumpulan karakter, alih-alih menggunakan rentang ascii untuk validasi.
sumber
sumber
Saya akan menggunakan seperti ini sehingga saya tidak perlu memanggil metode konversi lagi
sumber
Lakukan decode, encode ulang dan bandingkan hasilnya dengan string asli
sumber
Imho ini sangat tidak mungkin. Semua solusi yang diposting gagal untuk string seperti "test" dan seterusnya. Jika dapat dibagi menjadi 4, tidak kosong atau kosong, dan jika merupakan karakter base64 yang valid, mereka akan lulus semua pengujian. Itu bisa banyak string ...
Jadi tidak ada solusi nyata selain mengetahui bahwa ini adalah string yang dikodekan berbasis 64 . Apa yang saya dapatkan adalah ini:
Saya berharap string yang didekodekan dimulai dengan struktur tertentu, jadi saya memeriksanya.
sumber
Tentu. Pastikan masing-masing karakter dalam
a-z
,A-Z
,0-9
,/
, atau+
, dan string berakhir dengan==
. (Setidaknya, itulah implementasi Base64 yang paling umum. Anda mungkin menemukan beberapa implementasi yang menggunakan karakter yang berbeda dari/
atau+
untuk dua karakter terakhir.)sumber
Ya, sejak Base64 menyandikan data biner ke dalam string ASCII menggunakan sekumpulan karakter terbatas, Anda cukup memeriksanya dengan ekspresi reguler ini:
/ ^ [A-Za-z0-9 \ = \ + \ / \ s \ n] + $ / s
yang akan memastikan bahwa string hanya berisi AZ, az, 0-9, '+', '/', '=', dan spasi.
sumber
=
karakter di bagian akhir. Jika padding itu tidak valid, itu bukan encoding base64 yang benar, meskipun cocok dengan regex Anda. Anda dapat mendemonstrasikan ini dengan menemukan string basis 64 dengan 1 atau 2=
di akhir, menghapusnya, dan mencoba memecahkan kodenya.Saya menyarankan membuat regex untuk melakukan pekerjaan itu. Anda harus memeriksa sesuatu seperti ini: [a-zA-Z0-9 + / =] Anda juga harus memeriksa panjang senar. Saya tidak yakin yang satu ini, tapi saya cukup yakin jika ada sesuatu yang dipangkas (selain bantalan "=") itu akan meledak.
Atau lebih baik lagi periksa pertanyaan stackoverflow ini
sumber
Saya baru saja memiliki persyaratan yang sangat mirip di mana saya membiarkan pengguna melakukan manipulasi gambar dalam sebuah
<canvas>
elemen dan kemudian mengirim gambar yang dihasilkan diambil.toDataURL()
ke backend. Saya ingin melakukan validasi server sebelum menyimpan gambar dan telah menerapkanValidationAttribute
menggunakan beberapa kode dari jawaban lain:Seperti yang Anda lihat, saya mengharapkan string jenis gambar / png, yang dikembalikan default
<canvas>
saat menggunakan.toDataURL()
.sumber
Periksa Base64 atau string normal
public bool IsBase64Encoded (String str)
{
}
sumber
Semua jawaban telah dicerna menjadi 1 fungsi yang memastikan 100% bahwa hasilnya akan akurat.
1) Gunakan fungsi seperti di bawah ini:
2) Di bawah ini fungsinya:
sumber
Saya suka Ide cek Ekspresi Reguler. Ekspresi Reguler bisa cepat, dan sesekali menghemat biaya pengkodean. Penyelidikan asli, memiliki pembaruan yang melakukan hal ini. Saya menemukan, bahwa saya tidak pernah bisa berasumsi bahwa string tidak akan nol. Saya akan memperluas fungsi Ekstensi untuk memeriksa string sumber untuk karakter null, atau hanya spasi.
sumber