- Base64 एनकोडिंग binary data को ASCII text में बदलने का तरीका है, जिससे storage और transmission के दौरान data के गलत interpret होने की संभावना कम होती है
- यह encryption नहीं, बल्कि representation format में बदलाव है, इसलिए encoded data को आसानी से वापस मूल text या file data में बदला जा सकता है
- 64 characters को 6 bits में represent किया जा सकता है, इसलिए Base64 का एक character 6-bit data रखता है, और 3 bytes (24 bits) चार Base64 characters में बदल जाते हैं
- HTML के Data URLs, email में binary transmission, और text-centric networks या URLs जैसे environments में यह उपयोगी है, जहां raw binary समस्या पैदा कर सकता है
- Ruby, C#, PHP, JavaScript, terminal का
base64command आदि कई languages और tools encoding/decoding functionality देते हैं
Base64 क्या बदलता है
- Base64 एनकोडिंग binary data को text में, और अधिक सटीक रूप से ASCII text में convert करती है
- result केवल नीचे दिए गए 64 characters का उपयोग करता है
A-Za-z0-9+/
- यह character set
<,>,\nजैसे characters के पुराने computers या programs में गलत interpret होने की स्थितियों से बचने के लिए safe character set के रूप में इस्तेमाल होता है "Ruby on Rails"को Base64 में encode करने परUnVieSBvbiBSYWlscw==बनता है- Base64 encryption नहीं है
- encoded data को मूल text में आसानी से वापस बदला जा सकता है
- यह data को छिपाता नहीं, केवल data की representation बदलता है
Base64 इस्तेमाल करने की स्थितियां
- Data URLs image जैसे file data को सीधे HTML के अंदर रखने देते हैं, और इसके लिए Base64-encoded text का उपयोग होता है
- example format
data:[<mime type>][;charset=<charset>][;base64],<encoded data>है - email में, ऐसे environment में भी जहां servers line breaks बदल सकते हैं, binary data को सुरक्षित रूप से रखने के लिए Base64 का उपयोग होता रहा है
- HTML source में image data सीधे डालते समय
<और>जैसे characters tags के रूप में interpret न हों, इसके लिए encoding जरूरी होती है - text या US-ASCII data process करने के लिए design किए गए networks के जरिए binary data store या transmit करते समय भी इसका उपयोग किया जा सकता है
- URL में डालने में कठिन characters वाले data को भेजते समय भी Base64 इस्तेमाल किया जा सकता है
- Base-family encodings objects को text editor से handle करने योग्य बनाती हैं, इसलिए कई applications में उनका उपयोग होता है
एनकोडिंग algorithm
- Base64 encoding निम्न क्रम में होती है
- text को binary representation में convert करना
- bits को 6-bit groups में बांटना
- हर 6-bit group को 0 से 63 तक के decimal number में convert करना
- इस number को Base64 alphabet के corresponding character में बदलना
- अगर आखिरी group में bits कम हों, तो
=या==को padding के रूप में जोड़ा जा सकता है - 64 characters को represent करने के लिए 6 bits चाहिए
2^6 = 64- एक Base64 number 6-bit data को दर्शाता है
- byte 8 bits का होता है, और 8 और 6 का सबसे नजदीकी common multiple 24 है
- 24 bits 3 bytes होते हैं
- 24 bits को चार 6-bit Base64 numbers से represent किया जाता है
“Akshay” encoding example
"Akshay"में हर character को ASCII number में बदलकर फिर binary में convert करने पर यह मिलता है01000001 01101011 01110011 01101000 01100001 01111001
- इसे 6-bit groups में बांटने पर यह मिलता है
010000 010110 101101 110011 011010 000110 000101 111001
- हर group को decimal में बदलने पर ये values मिलती हैं
16 22 45 51 26 6 5 57
- Base64 alphabet में convert करने पर ये characters बनते हैं
Q W t z a G F 5
- इसलिए
"Akshay"का Base64 representationQWtzaGF5है - इसी तरह image, PDF, text, video जैसी files को भी binary में बदलकर Base64 में encode करने पर ASCII text के रूप में store या transmit किया जा सकता है
Languages और tools में उपयोग
- Ruby
Base64module से encoding और decoding handle करता हैBase64.encode64("Ruby on Rails")Base64.decode64(encoded)
- C# string को byte array में बदलकर
Convert.ToBase64Stringसे encode करता है, औरSystem.Convert.FromBase64Stringसे decode करता है - PHP top-level functions
base64_encodeऔरbase64_decodeदेता है - JavaScript
btoa()से encode औरatob()से decode करता है - terminal में भी
base64command से encoding और decoding की जा सकती हैecho "akshay" | base64YWtzaGF5Cg==output करता हैecho "YWtzaGF5Cg==" | base64 -dakshayoutput करता है
1 टिप्पणियां
Hacker News की राय
यह बात ज़ोर देकर बताने के लिए धन्यवाद कि यहाँ टेक्स्ट को encrypt नहीं किया जा रहा है। बहुत से junior developers encryption (जिसे reverse करने के लिए कोई secret value चाहिए), hashing (जिसे reverse नहीं किया जा सकता), और encoding (जिसे हमेशा आसानी से reverse किया जा सकता है) के बीच का फर्क बहुत देर से सीखते हैं और नुकसान उठा बैठते हैं
यह भी जानने लायक है कि output भले ही random जैसा दिखे, entropy input जितनी ही रहती है। यानी password को ज़्यादा मजबूत बनाने के लिए उसे Base64 में encode नहीं करना चाहिए
अगर password पूरी तरह random तरीके से generate किया गया है, तो Base64 encoding का कोई असर नहीं होगा। लेकिन अगर password किसी low-entropy system से बना है, जैसे dictionary words या याद रखने में आसान नियम, तो attacker को अपने smart password cracker में Base64 encoding rule को भी consider करने के लिए configure करना पड़ेगा, जिससे हर attempt में लगभग एक अतिरिक्त operation जुड़ जाएगा
बेशक, ऐसा password system इस्तेमाल नहीं करना चाहिए। “correct horse battery staple” जैसे password पर्याप्त माने जा सकते हैं
hashing के security के अलावा भी कई उद्देश्य होते हैं, इसलिए hash libraries भी कई तरह की होती हैं। अगर security या crypto-related use के लिए hash इस्तेमाल करना है, तो उसी उद्देश्य के लिए designed hash इस्तेमाल करना चाहिए। CRC hash तेज़ होते हैं, लेकिन user passwords के लिए अच्छे नहीं हैं
Base64 की एक दिलचस्प बात यह है कि अगर आप किसी string से शुरू करके encoding बार-बार दोहराएँ, तो result का शुरुआती हिस्सा धीरे-धीरे एक fixed point की ओर converge करता है। इसे Bash में भी देखा जा सकता है
10 साल से भी ज़्यादा पहले मैंने इसे संयोग से खोजा और cipher की तरह tweet किया था [1], फिर किसी ने उस विषय पर blog post लिखी और यहाँ भी post किया, लेकिन चर्चा ज़्यादा नहीं हुई [2]। किसी और ने इसे Reddit /r/compsci पर post किया, तो वहाँ blog post को correct करने वाली productive चर्चा हुई [3]। अब blog down है, लेकिन Internet Archive में उसकी copy बची हुई है [4]
[1] https://twitter.com/p4bl0/status/298900842076045312
[2] https://news.ycombinator.com/item?id=5181256
[3] https://www.reddit.com/r/compsci/comments/18234a/the_base64_...
[4] https://web.archive.org/web/20130315082932/http://fmota.eu/b...
Bash में encode करते समय
-noption इस्तेमाल करना चाहिए:$ echo -n "abcde" |base64-nन हो तोechostring के अंत में एक newline character जोड़ देता है, और वह character भी encode हो जाता हैechoइस्तेमाल न करके printf इस्तेमाल करना बेहतर है। https://linux.die.net/man/1/printfbase64URL भी होता है, जो URL-safe दूसरे ASCII characters का इस्तेमाल करके encode करता है। कुछ developers BASE64URL को बस base64 भी कह देते हैं, जिससे जिन लोगों को यह पता नहीं होता, उन्हें समस्या हो सकती है
https://datatracker.ietf.org/doc/html/rfc4648#section-5
~और.letters नहीं हैं, इसलिए encoded value पर double-click करने पर पूरी value select नहीं होती। copy-paste करने के कई मामलों में यह unnecessary friction बन जाता हैBase62 encoding (
0-9A-Za-z) base64url जितनी ही लगभग efficient है और URL safety भी बनाए रखती है, जबकि copy-paste करना आसान बनाती है। अगर इंसानों के पढ़ते समय ambiguity कम करनी हो, तो Base58 तक नीचे जा सकते हैं, लेकिन आमतौर पर जब BaseXX encoding की जा रही होती है, तो length लंबी होती है और copy-paste ही सामान्य होता है, इसलिए यह बड़ी समस्या नहीं होतीhttps://en.wikipedia.org/wiki/Base62
padding वाली Base64 string की length हमेशा 4 का multiple होती है, इसलिए अगर 4 का multiple न होने वाली string मिले, तो पता चल सकता है कि original padding कितनी होनी चाहिए थी और last 3 bytes को कैसे decode करना है
इसलिए यह थोड़ा confusing है कि Base64 में शुरू से ही
==padding की जरूरत क्यों हैbase conversion की बात आते ही मैं अपना arbitrary base converter बेधड़क promote करता हूँ: https://convert.zamicol.com
“useful alphabets” के नीचे base64, radix से repeated division करने वाला “natural” base है, और RFC की “bucket” conversion method extras के नीचे है
अगर आपने कुछ encode किया है और उसे इंसान को खुद type करना है, तो https://en.wikipedia.org/wiki/Base32 recommend करता हूँ
खराब fonts की वजह से
lहै या1,oहै याOया0, यह confuse होने जितना परेशान करने वाला कुछ नहींथोड़ा strict होकर कहें, तो Base64 के लिए यह कहना ज़्यादा सही है कि वह binary data को पूरे ASCII character set में नहीं, बल्कि ASCII subset में encode करता है
ASCII में 128 code points होते हैं, जिनमें 95 printable characters और 33 control characters हैं; Base64 उनमें से सिर्फ 64 characters इस्तेमाल करता है, और padding शामिल करें तो 65
लेख में
=/==padding का उद्देश्य विस्तार से नहीं बताया गया, और 6-bit groups में ठीक-ठीक न बंटने वाले data को कैसे handle किया जाता है, यह भी example से नहीं दिखाया गयामोटे तौर पर समझ तो आ गया लगता है, लेकिन पक्का जानना चाहता/चाहती हूँ।
=कब इस्तेमाल होता है और==कब, क्या इसे हमेशा add करते हैं या कभी नहीं भी लगाते,"5byte"जैसी string के बचे हुए bits को ठीक-ठीक कैसे handle किया जाता है, decoding करते समय किन बातों का ध्यान रखना होता है—अगर इसका छोटा और पूरा जवाब मिल सके तो अच्छा होगाBase64 का एक character 6 bits को represent करता है, इसलिए data का एक 3-byte block Base64-encoded characters के 4-character block से match करता है। इसी वजह से Base64 data को 4 characters के groups में process करना सुविधाजनक होता है
=padding है, जिसे encoded string की length को 4 के multiple में लाने के लिए जरूरत के हिसाब से 0, 1 या 2 बार लगाया जाता है। उदाहरण के लिए"543210"→"543210==","6543210"→"6543210=", और"76543210"में padding की जरूरत नहीं होती। padding में=तीन बार चाहिए ऐसा कभी नहीं होता, क्योंकि 1 byte data के लिए भी कम से कम 2 Base64 characters चाहिए होते हैंबचे हुए bits को 0 से भर सकते हैं, और decoder यह देखकर उन्हें discard कर सकता है कि पूरा 1 byte बनाने के लिए पर्याप्त bits नहीं हैं। आजकल ज्यादातर cases में padding सख्त जरूरत से ज्यादा एक convention जैसा है। Wikipedia article काफी detailed है: https://en.wikipedia.org/wiki/Base64
stream·file·string के अंत में मौजूद padding characters को पहले से process की गई length से infer किया जा सकता है, इसलिए कड़ाई से देखें तो वे अनिवार्य नहीं हैं
हालांकि padding handle करने का तरीका काफी subtle है, और उन्हीं फर्कों की वजह से interesting implementation variants बने हैं: https://eprint.iacr.org/2022/361.pdf
आखिरकार यह 24-bit units में encoding करने जैसा है। data खत्म होने पर बचे हुए 24-bit हिस्से को
Aसे नहीं बल्कि=से भरा जाता है, क्योंकिAdata के रूप में000000का मतलब रखता है। मैंने भी समझने के लिए पूरा text दो बार पढ़ामेरा Base64 encoder shader यहाँ है: https://github.com/Rezmason/excel_97_egg/blob/main/glsl/base...
इसे GLSL में लगभग 13 lines तक घटाया है: https://github.com/Rezmason/excel_97_egg/blob/main/glsl/base...
इसे एक side project के Cursed Mode में इस्तेमाल करता/करती हूँ, जहाँ WebGL framebuffer को Base64-encoded 640x480 pixel indexed color BMP के रूप में लगभग 15 बार प्रति सेकंड render किया जाता है: https://rezmason.github.io/excel_97_egg/?cursed=1
गहराई में जाने लगें तो कुछ और दिलचस्प details हैं, और उन details के variants भी हैरान करने लायक बहुत हैं
अगर input data की length ठीक 3 bytes की multiple नहीं है, तो आखिरी 1 byte या 2 bytes को encode करने के लिए 2 या 3 Base64 characters इस्तेमाल होते हैं। चूँकि एक Base64 character 6 bits का होता है, 8 bits या 16 bits को represent करने के लिए 12 bits या 18 bits इस्तेमाल होते हैं, और नतीजे में extra 4 bits या 2 bits बचते हैं जो कुछ भी encode नहीं करते
RFC encoder से अपेक्षा करता है कि वह उन bits को 0 set करे, लेकिन decoder के बारे में केवल इतना कहा गया है कि वह ऐसे input को reject कर सकता है जिनमें वे bits 0 नहीं हैं। असल में default रूप से reject करने वाली implementations बहुत कम हैं, और मेरी जानकारी में Ruby, Rust और Go ही ऐसी input पर fail होने के लिए configure किए जा सकते हैं। Python में
validateoption है, लेकिन वह उन bits को validate नहीं करताएक और बड़ा फर्क whitespace और non-Base64 characters को handle करने में है। Python समेत surprisingly कई implementations input के arbitrary characters को चुपचाप ignore कर देती हैं। alphabet गलत चुनने पर समस्या हो सकती है; उदाहरण के लिए Python में
base64.standard_b64decode(base64.urlsafe_b64encode(b'\xFF\xFE\xFD\xFC'))error नहीं देता और चुपचाप गलत output देता हैRuby के Base64 encoder का हर 60 characters पर newline डालना भी दिलचस्प है। PEM के अलावा कोई standard encoding इतनी छोटी lines की मांग नहीं करती, और PEM ठीक 64-character lines मांगता है, इसलिए यह काफी unusual choice है
मैंने programming languages और कुछ JavaScript libraries के बीच फर्कों को summarize करने वाला लेख लिखा है [1], और JS में बेहतर Base64 जोड़ने पर भी काम कर रहा/रही हूँ [2]
[1] https://gist.github.com/bakkot/16cae276209da91b652c2cb3f612a...
[2] https://github.com/tc39/proposal-arraybuffer-base64