Saya memiliki data biner dalam variabel char yang tidak ditandatangani. Saya perlu mengubahnya menjadi PEM base64 di c. Saya melihat di perpustakaan openssl tetapi saya tidak dapat menemukan fungsi apa pun. Apakah ada yang punya ide?
131
Jawaban:
Inilah yang saya gunakan:
Perlu diingat bahwa ini tidak melakukan pengecekan kesalahan saat decoding - data yang disandikan bukan basis 64 akan diproses.
sumber
*output_length = ((input_length - 1) / 3) * 4 + 4;
di awal base64_encode.build_decoding_table
.encoding_table[64]
untukencoding_table[255]
tidak ada.Saya tahu pertanyaan ini sudah cukup lama, tetapi saya semakin bingung dengan jumlah solusi yang diberikan - masing-masing dari mereka mengklaim lebih cepat dan lebih baik. Saya mengumpulkan sebuah proyek di github untuk membandingkan encoder dan decoder base64: https://github.com/gaspardpetit/base64/
Pada titik ini, saya belum membatasi diri pada algoritma C - jika satu implementasi berkinerja baik dalam C ++, dapat dengan mudah di-backport ke C. Juga tes dilakukan menggunakan Visual Studio 2015. Jika seseorang ingin memperbarui jawaban ini dengan hasil dari dentang / gcc, jadilah tamuku.
ENCODERS TERCEPAT: Dua implementasi encoder tercepat yang saya temukan adalah Jouni Malinen di http://web.mit.edu/freebsd/head/contrib/wpa/src/utils/base64.c dan Apache di https://opensource.apple .com / source / QuickTimeStreamingServer / QuickTimeStreamingServer-452 / CommonUtilitiesLib / base64.c .
Inilah saatnya (dalam mikrodetik) untuk menyandikan 32 ribu data menggunakan berbagai algoritma yang telah saya uji sampai sekarang:
(Solusi René Nyffenegger, dikreditkan dalam jawaban lain untuk pertanyaan ini, tercantum di sini sebagai adp_gmbh).
Inilah yang dari Jouni Malinen yang sedikit saya modifikasi untuk mengembalikan string std :::
DECODERS TERCEPAT: Berikut adalah hasil decoding dan saya harus mengakui bahwa saya sedikit terkejut:
Cuplikan Polfosol dari cuplikan decode base64 di c ++ adalah yang tercepat dengan faktor hampir 2x.
Berikut adalah kode demi kelengkapan:
sumber
char* outStr
parameter lain dan tulis ke buffer itu alih-alih mengembalikanstd::string
jika Anda mau, itu sepele untuk dilakukan. Sebelum saya memposting ini, sudah ada dua jawaban C ++ dengan upvotes di sini.Tetapi Anda juga dapat melakukannya di openssl (
openssl enc
perintah melakukannya ....), lihatBIO_f_base64()
fungsinyasumber
Inilah solusi saya menggunakan OpenSSL.
sumber
cc -o base base.c -lssl -lcrypto
. Tidak ada kesalahan Ini menghasilkan output ini:Original character string is: Base64 encode this string! Base-64 encoded string is: QmFzZTY0IGVuY29kZSB0aGlzIHN0cmluZyE= Base-64 decoded string is: Base64 encode this string!
glib memiliki fungsi untuk pengkodean base64: https://developer.gnome.org/glib/stable/glib-Base64-Encoding.html
sumber
libb64 memiliki API C dan C ++. Ini ringan dan mungkin implementasi tercepat yang tersedia untuk umum. Ini juga merupakan pustaka pengkodean base64 yang berdiri sendiri khusus, yang bisa menyenangkan jika Anda tidak memerlukan semua hal lain yang berasal dari menggunakan pustaka yang lebih besar seperti OpenSSL atau glib.
sumber
#define BUFFERSIZE 16777216
Anda dapat mengganti ke 65536 jika Anda membutuhkan buffer yang lebih kecil.char
masuk pada sistem target ... Ini adalah masalah karenabase64_decode_value
dapat mengembalikan angka negatif yang kemudian dicor ke char.GNU coreutils memilikinya di lib / base64. Ini sedikit membengkak tetapi berkaitan dengan hal-hal seperti EBCDIC. Anda juga dapat bermain-main sendiri, misalnya,
Ketahuilah kamu semua orang dengan hadiah-hadiah ini bahwa kamu tidak boleh bingung "bermain-main sendiri" dengan "menerapkan standar." Ya.
sumber
'+'
adalah 62 dan'/'
63 di PEM base64 seperti yang diminta oleh OP. Berikut adalah daftar varian pengkodean base64 . Saya tidak melihat varian encoding base64 dengan urutan karakter yang Anda gunakan. Tetapi matematika di balik algoritma itu benar.Saya membutuhkan implementasi C ++ yang bekerja pada std :: string . Tidak ada jawaban yang memuaskan kebutuhan saya, saya membutuhkan solusi dua-fungsi sederhana untuk encoding dan decoding, tetapi saya terlalu malas untuk menulis kode sendiri, jadi saya menemukan ini:
http://www.adp-gmbh.ch/cpp/common/base64.html
Kredit untuk kode masuk ke René Nyffenegger.
Masukkan kode di bawah jika situs turun:
base64.cpp
base64.h
Pemakaian
sumber
Inilah dekoder yang telah saya gunakan selama bertahun-tahun ...
sumber
UnBase64
fungsi Anda dapat membahayakan memori setelah buffer dest, jika buffer tersebut adalah ukuran yang tepat yang diperlukan untuk mendekode string base 64 yang disandikan. Ambil contoh kasus sederhana di mana Anda mencoba untuk memecahkan kode basis 64 yang dikodekan string "BQ ==", ke dalam BYTE tunggal yaituunsigned char Result = 0; UnBase64(&Result, "BQ==", 4);
akan merusak tumpukan!Dalam kasus orang membutuhkan solusi c ++, saya menempatkan solusi OpenSSL ini bersama-sama (untuk kedua encode dan decode). Anda harus terhubung dengan perpustakaan "crypto" (yang merupakan OpenSSL). Ini telah diperiksa untuk kebocoran dengan valgrind (walaupun Anda dapat menambahkan beberapa kode pemeriksaan kesalahan tambahan untuk membuatnya sedikit lebih baik - Saya tahu setidaknya fungsi tulis harus memeriksa nilai kembali).
sumber
Saya menulis satu untuk digunakan dengan C ++, ini sangat cepat, bekerja dengan stream, gratis, dan open source:
https://tmplusplus.svn.sourceforge.net/svnroot/tmplusplus/trunk/src/
Jangan ragu untuk menggunakannya jika itu sesuai dengan tujuan Anda.
Edit: Menambahkan kode sebaris berdasarkan permintaan.
Peningkatan kinerja diperoleh dengan menggunakan tabel pencarian untuk penyandian dan decoding.
_UINT8
adalahunsigned char
pada kebanyakan OS.sumber
Perbaikan kecil untuk kode dari ryyst (yang mendapat suara terbanyak) adalah untuk tidak menggunakan tabel decoding yang dialokasikan secara dinamis tetapi tabel precomputed const statis. Ini menghilangkan penggunaan pointer dan inisialisasi tabel, dan juga menghindari kebocoran memori jika seseorang lupa untuk membersihkan tabel decoding dengan base64_cleanup () (omong-omong, di base64_cleanup (), setelah memanggil bebas (decoding_table), orang seharusnya memiliki decoding_table = NULL, jika tidak sengaja memanggil base64_decode setelah base64_cleanup () akan macet atau menyebabkan perilaku yang tidak ditentukan). Solusi lain bisa menggunakan std :: unique_ptr ... tapi saya puas dengan hanya memiliki const char [256] pada stack dan hindari menggunakan pointer sama sekali - kode terlihat lebih bersih dan lebih pendek dengan cara ini.
Tabel pendekodean dihitung sebagai berikut:
dan kode yang dimodifikasi yang saya gunakan adalah:
sumber
Ini adalah dekoder yang secara khusus ditulis untuk menghindari kebutuhan buffer, dengan menulis langsung ke fungsi putchar. Ini didasarkan pada implementasi wikibook https://en.wikibooks.org/wiki/Algorithm_Implementation/Miscellaneous/Base64#C
Ini tidak mudah digunakan seperti opsi lain di atas. Namun, ini bisa digunakan dalam sistem tertanam, di mana Anda ingin membuang file besar tanpa mengalokasikan buffer besar lainnya untuk menyimpan string datauri base64 yang dihasilkan. (Sayang sekali bahwa datauri tidak membiarkan Anda menentukan nama file).
Ini tesnya
Output yang Diharapkan:
data:text/plain;charset=utf-8;base64,dGVzdA==
sumber
The
EVP_EncodeBlock
danEVP_DecodeBlock
fungsi membuatnya sangat mudah:sumber
Solusi ini didasarkan pada jawaban schulwitz (encoding / decoding menggunakan OpenSSL), tetapi untuk C ++ (well, pertanyaan asli adalah tentang C, tetapi sudah ada jawaban C ++ lainnya di sini) dan menggunakan pengecekan kesalahan (sehingga lebih aman untuk digunakan) :
Perhatikan bahwa base64_decode mengembalikan string kosong, jika input salah urutan base64 (openssl bekerja dengan cara seperti itu).
sumber
Berikut ini adalah versi yang dioptimalkan dari encoder untuk jawaban yang diterima, yang juga mendukung line-breaking untuk MIME dan protokol lainnya (optimasi simlar dapat diterapkan ke decoder):
sumber