Tidak, tidak - pertanyaan yang ditautkan lebih baru. Jadi itu membuat pertanyaan terkait duplikat dari yang ini ...
serge
Jawaban:
206
Tidak, Anda perlu menyandi-urlnya, karena string base64 dapat berisi karakter "+", "=" dan "/" yang dapat mengubah arti data Anda - terlihat seperti sub-folder.
URLencoding adalah pemborosan ruang, terutama karena base64 itu sendiri meninggalkan banyak karakter yang tidak digunakan.
Michał Górny
21
Saya tidak yakin saya mengerti apa yang Anda katakan - Pengkodean URL tidak akan mengubah salah satu karakter kecuali tiga karakter terakhir dalam daftar di atas, dan itu untuk mencegah mereka dari ditafsirkan secara salah karena mereka memiliki arti lain dalam URL. Hal yang sama berlaku untuk base64, data asli bisa berupa biner atau apa pun, tetapi dikodekan dalam bentuk yang dapat ditransmisikan dengan mudah menggunakan protokol sederhana.
Thiyagaraj
3
Pertama, Anda harus melarikan diri '+' juga karena dapat dikonversi menjadi ruang. Kedua, setidaknya ada beberapa karakter yang aman untuk digunakan dalam URL dan tidak digunakan dalam rangkaian karakter 'standar'. Metode Anda bahkan dapat meningkatkan ukuran data yang ditransfer tiga kali dalam situasi tertentu; sementara mengganti karakter tersebut dengan yang lain akan melakukan trik sambil mempertahankan panjang yang sama. Dan itu juga solusi standar.
Karena jawaban ini, saya mendiagnosis masalah saya persis seperti yang disebutkan. Beberapa 64 karakter dasar (+, /, =) sedang diubah karena pemrosesan URL. Ketika saya menyandikan URL base 64 string, masalahnya telah teratasi.
Chuck Krutsinger
272
Ada spesifikasi base64 tambahan. (Lihat tabel di sini untuk rinciannya). Tetapi pada dasarnya Anda membutuhkan 65 karakter untuk menyandikan: 26 huruf kecil + 26 huruf besar + 10 digit = 62.
Anda membutuhkan dua lagi ['+', '/'] dan char padding '='. Tapi tidak satu pun dari mereka yang ramah url, jadi gunakan saja karakter yang berbeda untuk mereka dan Anda siap. Yang standar dari bagan di atas adalah ['-', '_'], tetapi Anda bisa menggunakan karakter lain selama Anda mendekodekannya sama, dan tidak perlu berbagi dengan yang lain.
function base64_url_encode($input){return strtr(base64_encode($input),'+/=','._-');}function base64_url_decode($input){return base64_decode(strtr($input,'._-','+/='));}
Solusi hebat, kecuali koma tidak dipasok dalam URL. Saya sarankan menggunakan '~' (tilde) atau '.' (titik) sebagai gantinya.
kralyk
11
@ kralyk: Saya merekomendasikan hanya menggunakan urlencodeseperti yang disarankan oleh jawaban rodrigo-silveira. Membuat dua fungsi baru untuk menghemat beberapa karakter dalam panjang url, itu seperti masuk ke rumah Anda melewati jendela alih-alih hanya menggunakan pintu.
Marco Demaio
5
@MarcoDemaio, tanpa mengetahui bagaimana itu akan digunakan, tidak mungkin untuk mengatakan bahwa itu hanya beberapa karakter. Setiap karakter yang disandikan akan memiliki panjang tiga kali lipat, dan mengapa tidak "+++ ..." menjadi string base64 yang valid? URL memiliki batas peramban, dan tiga kali lipat URL mungkin membuat Anda mencapai batas itu.
leewz
10
@RandalSchwartz tilde yaitu URL-aman. Dari RFC3986:unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
@ joeshmo Atau alih-alih menulis fungsi pembantu, Anda bisa urlencode string base64 yang dikodekan. Ini akan melakukan hal yang sama persis dengan fungsi pembantu Anda, tetapi tanpa perlu dua fungsi tambahan.
Hasilnya tidak persis sama. urlencode menggunakan 3 karakter untuk mengkodekan karakter yang tidak valid dan solusi joeshmo menggunakan 1. Ini bukan perbedaan besar, tetapi masih sia-sia.
Josef Borkovec
1
@ JosefBorkovec Benarkah? Maka ini juga akan berarti jumlah byte yang sama base64-> url-> yang dikodekan bisa berupa berbagai panjang yang dihasilkan berbeda, sedangkan solusi lain memberikan panjang yang dapat diprediksi, kan?
humanityANDpeace
@ humanityANDpeace Ya, urlencode adalah solusi menyebalkan karena tiga kali lipat ukuran string base64 tertentu. Anda juga tidak dapat menggunakan kembali buffer karena output lebih besar dari input.
Navin
4
Ekspansi dari 1 hingga 3 karakter terjadi pada 3 dari 64 karakter rata-rata, sehingga merupakan biaya overhead 9% (2 *
3/64
Hati-hati dengan /karakter jika Anda meneruskannya bukan sebagai parameter GET, tetapi sebagai jalur di URL. Ini akan mengubah jalur Anda jika Anda tidak mengganti /dengan yang lain di kedua sisi.
NeverEndingQueue
41
Catatan Pengantar Saya cenderung memposting beberapa klarifikasi karena beberapa jawaban di sini sedikit menyesatkan (jika tidak salah).
Jawabannya adalah TIDAK , Anda tidak bisa hanya melewatkan parameter yang disandikan base64 dalam string kueri URL karena tanda plus dikonversi ke SPACE di dalam array global $ _GET. Dengan kata lain, jika Anda mengirim test.php? MyVar = stringwith + sign to
//test.phpprint $_GET['myVar'];
hasilnya adalah: stringwith sign
Cara mudah untuk menyelesaikan ini adalah dengan cukup urlencode()menggunakan string base64 Anda sebelum menambahkannya ke string kueri untuk keluar dari kode +, =, dan / karakter ke kode% ##. Misalnya, urlencode("stringwith+sign")kembalistringwith%2Bsign
Saat Anda memproses tindakan, PHP menangani penguraian kode string secara otomatis saat mengisi $ _GET global. Sebagai contoh, jika saya mengirim test.php? MyVar = stringwith% 2Bergabung ke
//test.phpprint $_GET['myVar'];
hasilnya adalah: stringwith+sign
Anda tidak ingin urldecode()string $ _GET yang dikembalikan karena + akan dikonversi menjadi spasi.
Dengan kata lain jika saya mengirim test.php yang sama ? MyVar = stringwith% 2Bsign ke
Jawaban bagus. Anda dapat menggunakan kode PHP tanpa tag awal dan akhir di situs ini jika pertanyaannya adalah tag php (juga paling sering jelas dari konteks pertanyaan). Jika Anda menambahkan dua spasi di akhir baris Anda akan melihat <br>, jadi tidak perlu mengetik banyak HTML. Saya harap ini membantu, saya sedikit mengedit jawaban Anda untuk lebih meningkatkannya.
hakre
Terima kasih telah menyebutkan bahwa PHP menerjemahkan URL untuk Anda. Itu menyelamatkan saya dari jatuh ke dalam lubang kelinci.
Cocest
Jawaban Hebat -> Anda tidak ingin urldecode () string $ _GET yang dikembalikan karena + akan dikonversi menjadi spasi. Akan lebih aman untuk menggunakan
kode mentah
14
Iya dan tidak.
Charset dasar base64 dalam beberapa kasus mungkin berbenturan dengan konvensi tradisional yang digunakan dalam URL. Tetapi banyak implementasi base64 memungkinkan Anda untuk mengubah charset agar sesuai dengan URL yang lebih baik atau bahkan datang dengan satu (seperti Python urlsafe_b64encode()).
Masalah lain yang mungkin Anda hadapi adalah batas panjang URL atau lebih tepatnya - kurangnya batas tersebut. Karena standar tidak menentukan panjang maksimal, browser, server, perpustakaan dan perangkat lunak lain yang bekerja dengan protokol HTTP dapat menentukan batasnya sendiri. Anda dapat melihat artikel ini: FAQ WWW: Berapa panjang maksimum URL?
Ini berfungsi untuk data yang disandikan dengan JavaBase64.getUrlEncoder().withoutPadding().encodeToString()
4
Saya tidak berpikir bahwa ini aman karena misalnya karakter "=" digunakan dalam basis mentah 64 dan juga digunakan dalam membedakan parameter dari nilai dalam GET HTTP.
Secara teori, ya, selama Anda tidak melebihi panjang string url dan / atau kueri maksimum untuk klien atau server.
Dalam praktiknya, berbagai hal bisa menjadi sedikit lebih rumit. Misalnya, ini dapat memicu HttpRequestValidationException di ASP.NET jika nilainya mengandung "on" dan Anda membiarkannya mengekor "==".
Ya, selalu aman. tentu saja base64 berisi:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
tetapi string yang disandikan base64 biasanya tidak memiliki +. +akan dikonversi menjadi ruang kosong, menghasilkan string yang salah diterjemahkan. /aman dalam pasangan parameter get. =selalu di akhir string yang disandikan base64 dan sisi server dapat menyelesaikan =secara langsung.
Saya kira ini benar, karena percobaan yang telah saya lakukan dengan pengkodean base64 (tanpa pengkodean url) telah berhasil, tetapi saya ingin tahu apakah ada dokumentasi yang dapat Anda berikan untuk mendukungnya?
Sean the Bean
1
Anda mengatakan "selalu aman" tetapi kemudian Anda mengatakan "biasanya tidak memiliki +". Jadi, Anda bertentangan dengan diri Anda sendiri. Tanda + jahitan menyebabkan masalah jika Anda memilikinya dalam string base64 Anda.
Jawaban:
Tidak, Anda perlu menyandi-urlnya, karena string base64 dapat berisi karakter "+", "=" dan "/" yang dapat mengubah arti data Anda - terlihat seperti sub-folder.
Karakter base64 yang valid ada di bawah ini.
sumber
Ada spesifikasi base64 tambahan. (Lihat tabel di sini untuk rinciannya). Tetapi pada dasarnya Anda membutuhkan 65 karakter untuk menyandikan: 26 huruf kecil + 26 huruf besar + 10 digit = 62.
Anda membutuhkan dua lagi ['+', '/'] dan char padding '='. Tapi tidak satu pun dari mereka yang ramah url, jadi gunakan saja karakter yang berbeda untuk mereka dan Anda siap. Yang standar dari bagan di atas adalah ['-', '_'], tetapi Anda bisa menggunakan karakter lain selama Anda mendekodekannya sama, dan tidak perlu berbagi dengan yang lain.
Saya sarankan hanya menulis pembantu Anda sendiri. Suka ini dari komentar di halaman manual php untuk base64_encode :
sumber
urlencode
seperti yang disarankan oleh jawaban rodrigo-silveira. Membuat dua fungsi baru untuk menghemat beberapa karakter dalam panjang url, itu seperti masuk ke rumah Anda melewati jendela alih-alih hanya menggunakan pintu.unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
,
harus dimasukkan ke urlencoded%2C
, saya sarankan menggunakan._-
alih-alih-_,
seperti satu-satunya varian di en.wikipedia.org/wiki/Base64#Variants_summary_table yang membuat trailing =@ joeshmo Atau alih-alih menulis fungsi pembantu, Anda bisa urlencode string base64 yang dikodekan. Ini akan melakukan hal yang sama persis dengan fungsi pembantu Anda, tetapi tanpa perlu dua fungsi tambahan.
sumber
/
karakter jika Anda meneruskannya bukan sebagai parameter GET, tetapi sebagai jalur di URL. Ini akan mengubah jalur Anda jika Anda tidak mengganti/
dengan yang lain di kedua sisi.Jawabannya adalah TIDAK , Anda tidak bisa hanya melewatkan parameter yang disandikan base64 dalam string kueri URL karena tanda plus dikonversi ke SPACE di dalam array global $ _GET. Dengan kata lain, jika Anda mengirim test.php? MyVar = stringwith + sign to
hasilnya adalah:
stringwith sign
Cara mudah untuk menyelesaikan ini adalah dengan cukup
urlencode()
menggunakan string base64 Anda sebelum menambahkannya ke string kueri untuk keluar dari kode +, =, dan / karakter ke kode% ##. Misalnya,urlencode("stringwith+sign")
kembalistringwith%2Bsign
Saat Anda memproses tindakan, PHP menangani penguraian kode string secara otomatis saat mengisi $ _GET global. Sebagai contoh, jika saya mengirim test.php? MyVar = stringwith% 2Bergabung ke
hasilnya adalah:
stringwith+sign
Anda tidak ingin
urldecode()
string $ _GET yang dikembalikan karena + akan dikonversi menjadi spasi.Dengan kata lain jika saya mengirim test.php yang sama ? MyVar = stringwith% 2Bsign ke
hasilnya tidak terduga:
stringwith sign
Akan aman untuk
rawurldecode()
input, namun, itu akan berlebihan dan karena itu tidak perlu.sumber
<br>
, jadi tidak perlu mengetik banyak HTML. Saya harap ini membantu, saya sedikit mengedit jawaban Anda untuk lebih meningkatkannya.Iya dan tidak.
Charset dasar base64 dalam beberapa kasus mungkin berbenturan dengan konvensi tradisional yang digunakan dalam URL. Tetapi banyak implementasi base64 memungkinkan Anda untuk mengubah charset agar sesuai dengan URL yang lebih baik atau bahkan datang dengan satu (seperti Python
urlsafe_b64encode()
).Masalah lain yang mungkin Anda hadapi adalah batas panjang URL atau lebih tepatnya - kurangnya batas tersebut. Karena standar tidak menentukan panjang maksimal, browser, server, perpustakaan dan perangkat lunak lain yang bekerja dengan protokol HTTP dapat menentukan batasnya sendiri. Anda dapat melihat artikel ini: FAQ WWW: Berapa panjang maksimum URL?
sumber
Ini adalah encode base64url yang dapat Anda coba, hanya perpanjangan kode joeshmo di atas.
sumber
Base64.getUrlEncoder().withoutPadding().encodeToString()
Saya tidak berpikir bahwa ini aman karena misalnya karakter "=" digunakan dalam basis mentah 64 dan juga digunakan dalam membedakan parameter dari nilai dalam GET HTTP.
sumber
Secara teori, ya, selama Anda tidak melebihi panjang string url dan / atau kueri maksimum untuk klien atau server.
Dalam praktiknya, berbagai hal bisa menjadi sedikit lebih rumit. Misalnya, ini dapat memicu HttpRequestValidationException di ASP.NET jika nilainya mengandung "on" dan Anda membiarkannya mengekor "==".
sumber
Untuk penyandian aman url, seperti
base64.urlsafe_b64encode(...)
pada Python kode di bawah ini, berfungsi untuk saya untuk 100%sumber
Ya, selalu aman. tentu saja base64 berisi:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
tetapi string yang disandikan base64 biasanya tidak memiliki+
.+
akan dikonversi menjadi ruang kosong, menghasilkan string yang salah diterjemahkan./
aman dalam pasangan parameter get.=
selalu di akhir string yang disandikan base64 dan sisi server dapat menyelesaikan=
secara langsung.sumber