Bagaimana cara memeriksa apakah suatu string Base64 dikodekan atau tidak
194
Saya ingin mendekodekan string yang disandikan Base64, lalu menyimpannya di basis data saya. Jika inputnya tidak di-encode Base64, saya perlu melakukan kesalahan.
Bagaimana saya bisa mengecek apakah suatu string di-base64?
tanpa menentukan bahasa pemrograman mana (dan / atau) Sistem Operasi yang Anda targetkan, ini adalah pertanyaan yang sangat terbuka
bcarroll
5
Yang dapat Anda tentukan adalah bahwa string tersebut hanya berisi karakter yang valid untuk string yang disandikan base64. Mungkin tidak mungkin untuk menentukan bahwa string adalah versi yang disandikan base64 dari beberapa data. misalnya test1234adalah string yang disandikan base64 yang valid, dan ketika Anda mendekodekannya Anda akan mendapatkan beberapa byte. Tidak ada aplikasi cara independen untuk menyimpulkan bahwa test1234bukan string yang disandikan base64.
Dalam pengkodean base64, set karakter adalah [A-Z, a-z, 0-9, and + /]. Jika panjang istirahat kurang dari 4, string diisi dengan '='karakter.
^([A-Za-z0-9+/]{4})* berarti string dimulai dengan 0 grup base64 atau lebih.
([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$berarti ujung string dalam salah satu dari tiga bentuk: [A-Za-z0-9+/]{4}, [A-Za-z0-9+/]{3}=atau [A-Za-z0-9+/]{2}==.
Hanya ingin memverifikasi, jadi tolong bantu dengan pertanyaan saya: Apa jaminan bahwa regex ini akan selalu merujuk hanya string base64 ?? Jika ada string yang tidak memiliki ruang dan itu adalah kelipatan dari 4 karakter, maka apakah string itu akan dianggap sebagai string base64 ????
DShah
3
Maka itu adalah string base64 yang valid yang dapat diterjemahkan. Anda bisa menambahkan batasan panjang minimum; misalnya, alih-alih nol atau lebih pengulangan dari kelompok empat, minta (katakanlah) empat atau lebih. Itu tergantung pada masalah Anda juga; jika pengguna Anda sering memasukkan satu kata dalam bahasa dengan kata-kata yang panjang dan ASCII murni (Hawaii?) lebih rentan kesalahan daripada jika input non-base64 biasanya berisi spasi, tanda baca, dll.
tripleee
62
Ini hanya memberi tahu bahwa suatu input bisa saja merupakan nilai yang dikodekan b64, tetapi itu tidak memberi tahu apakah input tersebut sebenarnya adalah nilai yang dikodekan b64. Dengan kata lain, abcdakan cocok, tetapi itu tidak selalu mewakili nilai yang dikodekan dari i·sekadar abcdinput biasa
Tzury Bar Yochay
3
Regexp Anda salah, karena tidak cocok dengan string kosong, dengan adalah base64 pengkodean data biner nol-panjang menurut RFC 4648.
kemerahan
5
@Adomas, "pass" adalah string base64 yang benar-benar valid, yang menerjemahkan ke dalam urutan byte 0xa5, 0xabdan 0x2c. Mengapa membuangnya secara apriori , jika Anda tidak memiliki konteks untuk memutuskan?
Luis Colorado
50
Jika Anda menggunakan Java, Anda sebenarnya dapat menggunakan perpustakaan commons-codec
dari dokumentasi: isArrayByteBase64(byte[] arrayOctet)Sudah usang. 1.5 Penggunaan isBase64(byte[]), akan dihapus dalam 2.0.
Avinash R
7
Anda dapat menggunakan juga Base64.isBase64 (String base64) alih-alih mengubahnya sendiri ke byte array.
Sasa
5
Sedihnya, berdasarkan pada dokumentasi: commons.apache.org/proper/commons-codec/apidocs/org/apache/… : "Menguji String yang diberikan untuk melihat apakah itu berisi hanya karakter yang valid dalam alfabet Base64. Saat ini metode memperlakukan spasi putih sebagai sah." Ini berarti bahwa metode ini memiliki beberapa positif palsu seperti "spasi putih" atau angka ("0", "1").
Christian Vielma
untuk string Base64.isBase64 (konten)
ema
3
Jawaban ini salah karena diberikan stringToBeChecked="some plain text"maka itu menetapkan boolean isBase64=truemeskipun itu bukan nilai yang disandikan Base64. Baca sumber untuk commons-codec-1.4 Base64.isArrayByteBase64()hanya memeriksa bahwa setiap karakter dalam string valid untuk dipertimbangkan untuk pengkodean Base64 dan memungkinkan ruang putih.
Brad
49
Anda bisa:
Pastikan panjangnya adalah kelipatan 4 karakter
Periksa bahwa setiap karakter ada di set AZ, az, 0-9, +, / kecuali untuk padding di bagian akhir yaitu 0, 1 atau 2 '=' karakter
Jika Anda mengharapkan bahwa itu akan menjadi base64, maka Anda mungkin bisa menggunakan pustaka apa saja yang tersedia di platform Anda untuk mencoba mendekodekannya ke array byte, melemparkan pengecualian jika itu bukan basis 64 yang valid. Itu tergantung pada platform Anda, tentu saja.
Parsing berbeda dari validasi setidaknya oleh fakta bahwa ia membutuhkan memori untuk byte array yang didekodekan. Jadi ini bukan pendekatan yang paling efektif dalam beberapa kasus.
Victor Yarema
1
@VictorYarema: Saya menyarankan pendekatan validasi saja (poin-poin) dan juga pendekatan parsing (setelah poin-poin).
Jon Skeet
16
Pada Java 8, Anda cukup menggunakan java.util.Base64 untuk mencoba dan mendekode string:
ya, itu sebuah pilihan, tetapi jangan lupa bahwa tangkapan adalah operasi yang cukup mahal di Jawa
panser
2
Bukan itu masalahnya lagi. Penanganan pengecualian berjalan cukup baik. Anda sebaiknya tidak lupa bahwa Java Regex sangat lambat. Maksud saya: BENAR-BENAR LAMBAT! Ini sebenarnya lebih cepat untuk memecahkan kode Base64 dan memeriksa apakah itu (tidak) berfungsi daripada mencocokkan String dengan Regex di atas. Saya melakukan tes kasar dan pencocokan Java Regex sekitar enam kali lebih lambat (!!) daripada menangkap pengecualian akhirnya pada decode.
Sven Döring
Dengan lebih banyak tes berjalan sebenarnya sebelas kali lebih lambat. Saatnya untuk implementasi Regex yang lebih baik di Jawa. Bahkan pemeriksaan Regex dengan mesin JavaScript Nashorn di Jawa jauh lebih cepat. Luar biasa. Selain itu JavaScript Regex (dengan Nashorn) jauh lebih kuat.
Sven Döring
3
Dengan Java 11 (bukan Java 8) pemeriksaan Regex bahkan 22 kali lebih lambat. 🤦 (Karena decoding Base64 menjadi lebih cepat.)
Sven Döring
15
Coba seperti ini untuk PHP5
//where $json is some data that can be base64 encoded
$json=some_data;
//this will check whether data is base64 encoded or not
if (base64_decode($json, true) == true)
{
echo "base64 encoded";
}
else
{
echo "not base64 encoded";
}
Gunakan ini untuk PHP7
//$string parameter can be base64 encoded or not
function is_base64_encoded($string){
//this will check if $string is base64 encoded and return true, if it is.
if (base64_decode($string, true) !== false){
return true;
}else{
return false;
}
}
Bahasa apa ini? Pertanyaan itu diajukan tanpa merujuk ke bahasa
Ozkan
ini tidak akan berhasil. baca docs Returns FALSE if input contains character from outside the base64 alphabet.base64_decode
Aley
1
Bagaimana? jika input mengandung karakter luar maka itu bukan base64, kan?
Suneel Kumar
6
var base64Rejex = /^(?:[A-Z0-9+\/]{4})*(?:[A-Z0-9+\/]{2}==|[A-Z0-9+\/]{3}=|[A-Z0-9+\/]{4})$/i;
var isBase64Valid = base64Rejex.test(base64Data); // base64Data is the base64 string
if (isBase64Valid) {
// true if base64 formate
console.log('It is base64');
} else {
// false if not in base64 formate
console.log('it is not in base64');
}
Periksa untuk melihat JIKA panjang string adalah kelipatan dari 4. Setelah itu gunakan regex ini untuk memastikan semua karakter dalam string adalah karakter base64.
\A[a-zA-Z\d\/+]+={,2}\z
Jika pustaka yang Anda gunakan menambahkan baris baru sebagai cara mengamati 76 maks karakter per baris, gantikan dengan string kosong.
Tautan yang disebutkan menunjukkan 404. Silakan periksa dan perbarui.
Ankur
Maaf @AnkurKumar tetapi itulah yang terjadi ketika orang-orang memiliki URL yang tidak keren: mereka berubah setiap saat. Saya tidak tahu ke mana ia dipindahkan. Saya harap Anda menemukan sumber daya lain yang bermanfaat melalui Google
Ada banyak varian Base64 , jadi pertimbangkan untuk menentukan apakah string Anda menyerupai varian yang ingin Anda tangani. Dengan demikian, Anda mungkin perlu menyesuaikan regex di bawah ini sehubungan dengan indeks dan padding karakter (yaitu +, /, =).
class String
def resembles_base64?
self.length % 4 == 0 && self =~ /^[A-Za-z0-9+\/=]+\Z/
end
end
Pemakaian:
raise 'the string does not resemble Base64' unless my_string.resembles_base64?
Tidak mungkin untuk memeriksa apakah string base64 dikodekan atau tidak. Itu hanya mungkin untuk memvalidasi jika string itu dari format string yang dienkode base64, yang berarti bahwa itu bisa menjadi string yang dihasilkan oleh pengkodean base64 (untuk memeriksa bahwa, string dapat divalidasi terhadap regexp atau perpustakaan dapat digunakan, banyak jawaban lain untuk pertanyaan ini memberikan cara yang baik untuk memeriksa ini, jadi saya tidak akan menjelaskan lebih lanjut).
Sebagai contoh, string flowadalah string yang disandikan base64 yang valid. Tetapi tidak mungkin untuk mengetahui apakah itu hanya string sederhana, kata bahasa Inggris flow, atau basis 64 string yang disandikan~Z0
ekspresi reguler ini membantu saya mengidentifikasi base64 dalam aplikasi saya di rails, saya hanya punya satu masalah, itu adalah mengenali string "errorDescripcion", saya menghasilkan kesalahan, untuk menyelesaikannya hanya memvalidasi panjang string.
Regex di atas /^.....$/.match(my_string) memberikan kesalahan pemformatan dengan mengatakan 'Penutupan tak tertandingi' '
james2611nov
Dan dengan 'prematur akhir char-class: / ^ (([A-Za-z0-9 + /' kesalahan sintaks.
james2611nov
Nevermind memperbaikinya dengan menambahkan \ di depan setiap / karakter.
james2611nov
errorDescriptionadalah base64 string yang valid, itu menerjemahkan ke dalam urutan biner byte (dalam hex): 7a ba e8 ac 37 ac 72 b8 a9 b6 2a 27.
Luis Colorado
Ini bekerja sempurna bagi saya untuk memeriksa string yang disandikan base64.
Deepak Lakhara
1
Ini berfungsi dalam Python:
import base64
def IsBase64(str):
try:
base64.b64decode(str)
return True
except Exception as e:
return False
if IsBase64("ABC"):
print("ABC is Base64-encoded and its result after decoding is: " + str(base64.b64decode("ABC")).replace("b'", "").replace("'", ""))
else:
print("ABC is NOT Base64-encoded.")
if IsBase64("QUJD"):
print("QUJD is Base64-encoded and its result after decoding is: " + str(base64.b64decode("QUJD")).replace("b'", "").replace("'", ""))
else:
print("QUJD is NOT Base64-encoded.")
Ringkasan:IsBase64("string here") mengembalikan true jika string heredikodekan Base64, dan itu mengembalikan false jika string hereTIDAK dikodekan Base64.
Cuplikan ini mungkin berguna saat Anda mengetahui panjang konten asli (mis. Checksum). Itu memeriksa bahwa bentuk disandikan memiliki panjang yang benar.
public static boolean isValidBase64( final int initialLength, final String string ) {
final int padding ;
final String regexEnd ;
switch( ( initialLength ) % 3 ) {
case 1 :
padding = 2 ;
regexEnd = "==" ;
break ;
case 2 :
padding = 1 ;
regexEnd = "=" ;
break ;
default :
padding = 0 ;
regexEnd = "" ;
}
final int encodedLength = ( ( ( initialLength / 3 ) + ( padding > 0 ? 1 : 0 ) ) * 4 ) ;
final String regex = "[a-zA-Z0-9/\\+]{" + ( encodedLength - padding ) + "}" + regexEnd ;
return Pattern.compile( regex ).matcher( string ).matches() ;
}
Jika RegEx tidak berfungsi dan Anda tahu gaya format string asli, Anda bisa membalikkan logikanya, dengan regexing untuk format ini.
Sebagai contoh saya bekerja dengan file xml yang disandikan base64 dan hanya memeriksa apakah file tersebut berisi markup xml yang valid. Jika tidak saya dapat berasumsi, bahwa itu base64 diterjemahkan. Ini tidak terlalu dinamis tetapi berfungsi baik untuk aplikasi kecil saya.
Coba ini menggunakan regex yang disebutkan sebelumnya:
String regex = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
if("TXkgdGVzdCBzdHJpbmc/".matches(regex)){
System.out.println("it's a Base64");
}
... Kami juga dapat membuat validasi sederhana seperti, jika memiliki spasi tidak boleh Base64:
String myString = "Hello World";
if(myString.contains(" ")){
System.out.println("Not B64");
}else{
System.out.println("Could be B64 encoded, since it has no spaces");
}
jika saat decoding kita mendapatkan string dengan karakter ASCII, maka string itu tidak dikodekan
(RoR) solusi ruby:
def encoded?(str)
Base64.decode64(str.downcase).scan(/[^[:ascii:]]/).count.zero?
end
def decoded?(str)
Base64.decode64(str.downcase).scan(/[^[:ascii:]]/).count > 0
end
test1234
adalah string yang disandikan base64 yang valid, dan ketika Anda mendekodekannya Anda akan mendapatkan beberapa byte. Tidak ada aplikasi cara independen untuk menyimpulkan bahwatest1234
bukan string yang disandikan base64.Jawaban:
Anda dapat menggunakan ekspresi reguler berikut untuk memeriksa apakah string dikodekan base64 atau tidak:
Dalam pengkodean base64, set karakter adalah
[A-Z, a-z, 0-9, and + /]
. Jika panjang istirahat kurang dari 4, string diisi dengan'='
karakter.^([A-Za-z0-9+/]{4})*
berarti string dimulai dengan 0 grup base64 atau lebih.([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$
berarti ujung string dalam salah satu dari tiga bentuk:[A-Za-z0-9+/]{4}
,[A-Za-z0-9+/]{3}=
atau[A-Za-z0-9+/]{2}==
.sumber
abcd
akan cocok, tetapi itu tidak selalu mewakili nilai yang dikodekan darii·
sekadarabcd
input biasa"pass"
adalah string base64 yang benar-benar valid, yang menerjemahkan ke dalam urutan byte0xa5
,0xab
dan0x2c
. Mengapa membuangnya secara apriori , jika Anda tidak memiliki konteks untuk memutuskan?Jika Anda menggunakan Java, Anda sebenarnya dapat menggunakan perpustakaan commons-codec
sumber
isArrayByteBase64(byte[] arrayOctet)
Sudah usang. 1.5 PenggunaanisBase64(byte[])
, akan dihapus dalam 2.0.stringToBeChecked="some plain text"
maka itu menetapkanboolean isBase64=true
meskipun itu bukan nilai yang disandikan Base64. Baca sumber untuk commons-codec-1.4Base64.isArrayByteBase64()
hanya memeriksa bahwa setiap karakter dalam string valid untuk dipertimbangkan untuk pengkodean Base64 dan memungkinkan ruang putih.Anda bisa:
Jika Anda mengharapkan bahwa itu akan menjadi base64, maka Anda mungkin bisa menggunakan pustaka apa saja yang tersedia di platform Anda untuk mencoba mendekodekannya ke array byte, melemparkan pengecualian jika itu bukan basis 64 yang valid. Itu tergantung pada platform Anda, tentu saja.
sumber
Pada Java 8, Anda cukup menggunakan java.util.Base64 untuk mencoba dan mendekode string:
sumber
Coba seperti ini untuk PHP5
Gunakan ini untuk PHP7
sumber
Returns FALSE if input contains character from outside the base64 alphabet.
base64_decodesumber
Periksa untuk melihat JIKA panjang string adalah kelipatan dari 4. Setelah itu gunakan regex ini untuk memastikan semua karakter dalam string adalah karakter base64.
\A[a-zA-Z\d\/+]+={,2}\z
Jika pustaka yang Anda gunakan menambahkan baris baru sebagai cara mengamati 76 maks karakter per baris, gantikan dengan string kosong.
sumber
Ada banyak varian Base64 , jadi pertimbangkan untuk menentukan apakah string Anda menyerupai varian yang ingin Anda tangani. Dengan demikian, Anda mungkin perlu menyesuaikan regex di bawah ini sehubungan dengan indeks dan padding karakter (yaitu
+
,/
,=
).Pemakaian:
sumber
Coba ini:
sumber
Tidak mungkin untuk memeriksa apakah string base64 dikodekan atau tidak. Itu hanya mungkin untuk memvalidasi jika string itu dari format string yang dienkode base64, yang berarti bahwa itu bisa menjadi string yang dihasilkan oleh pengkodean base64 (untuk memeriksa bahwa, string dapat divalidasi terhadap regexp atau perpustakaan dapat digunakan, banyak jawaban lain untuk pertanyaan ini memberikan cara yang baik untuk memeriksa ini, jadi saya tidak akan menjelaskan lebih lanjut).
Sebagai contoh, string
flow
adalah string yang disandikan base64 yang valid. Tetapi tidak mungkin untuk mengetahui apakah itu hanya string sederhana, kata bahasa Inggrisflow
, atau basis 64 string yang disandikan~Z0
sumber
ekspresi reguler ini membantu saya mengidentifikasi base64 dalam aplikasi saya di rails, saya hanya punya satu masalah, itu adalah mengenali string "errorDescripcion", saya menghasilkan kesalahan, untuk menyelesaikannya hanya memvalidasi panjang string.
sumber
errorDescription
adalah base64 string yang valid, itu menerjemahkan ke dalam urutan biner byte (dalam hex):7a ba e8 ac 37 ac 72 b8 a9 b6 2a 27
.Ini berfungsi dalam Python:
Ringkasan:
IsBase64("string here")
mengembalikan true jikastring here
dikodekan Base64, dan itu mengembalikan false jikastring here
TIDAK dikodekan Base64.sumber
C # Ini berkinerja bagus:
sumber
Console.WriteLine("test".IsBase64()); // true
Tidak ada cara untuk membedakan string dan base64, kecuali string di sistem Anda memiliki beberapa batasan atau identifikasi tertentu.
sumber
Cuplikan ini mungkin berguna saat Anda mengetahui panjang konten asli (mis. Checksum). Itu memeriksa bahwa bentuk disandikan memiliki panjang yang benar.
sumber
Jika RegEx tidak berfungsi dan Anda tahu gaya format string asli, Anda bisa membalikkan logikanya, dengan regexing untuk format ini.
Sebagai contoh saya bekerja dengan file xml yang disandikan base64 dan hanya memeriksa apakah file tersebut berisi markup xml yang valid. Jika tidak saya dapat berasumsi, bahwa itu base64 diterjemahkan. Ini tidak terlalu dinamis tetapi berfungsi baik untuk aplikasi kecil saya.
sumber
Ini berfungsi dalam Python:
sumber
Coba ini menggunakan regex yang disebutkan sebelumnya:
... Kami juga dapat membuat validasi sederhana seperti, jika memiliki spasi tidak boleh Base64:
sumber
(RoR) solusi ruby:
sumber
Saya mencoba menggunakan ini, ya ini berhasil
tapi saya menambahkan syarat untuk memeriksa setidaknya karakter adalah =
sumber
=
: Spesifikasi apaBase64
yang Anda gunakan? Apaend of the character
artinya, dan bagaimanalastIndexOf()
pemeriksaan non-negatif itu?