Base64: อะไรคือการเพิ่มขึ้นของการใช้พื้นที่ที่แย่ที่สุด?


168

หากเซิร์ฟเวอร์ได้รับสตริง base64 และต้องการตรวจสอบความยาวของมันก่อนที่จะทำการแปลงสมมติว่ามันต้องการอนุญาตให้อาร์เรย์ไบต์สุดท้ายเป็น 16KB เสมอ อาร์เรย์ 16KB ไบต์นั้นมีขนาดใหญ่เพียงใดเมื่อแปลงเป็นสตริง Base64 (สมมติว่าหนึ่งไบต์ต่ออักขระ)

คำตอบ:


245

Base64 เข้ารหัสแต่ละชุดของสามไบต์เป็นสี่ไบต์ นอกจากนี้เอาต์พุตจะถูกเพิ่มเป็นหลายเท่าของสี่เสมอ

ซึ่งหมายความว่าขนาดของการแสดงฐาน -64 ของสตริงที่มีขนาด n คือ:

ceil(n / 3) * 4

ดังนั้นสำหรับอาร์เรย์ขนาด 16kB การแทนค่าฐาน 64 จะเป็นเพดาน (16 * 1024/3) * 4 = 21848 ไบต์ยาว ~ = 21.8kB

การประมาณคร่าวๆจะเป็นไปได้ว่าขนาดของข้อมูลจะเพิ่มขึ้นเป็น 4/3 ของต้นฉบับ


เราจำเป็นต้องเพิ่ม 2 ความยาวหรือไม่?
vIceBerg

@vIceBerg ขึ้นอยู่กับว่าคุณใช้ceilกับfloatตัวเลขหรือเป็นเพียงintตัวเลข (และไม่ใช่ceil)
ฟิลด์ Bryan

7
ฉันเดาว่าวิธีที่ง่ายกว่านี้คือคุณเพิ่มขนาด 1/3 ของเดิม
mvmn

1
ในตัวอย่างที่คุณเสนอการแสดงผลลัพธ์ในลำดับการวัดเดียวกันจะเพิ่มคุณภาพของคำตอบเล็กน้อย (21,3 KB แทน 21848 ไบต์)
Ivan De Paz Centeno

36

จากวิกิพีเดีย

โปรดทราบว่าเมื่อได้รับอินพุตของ n ไบต์เอาต์พุตจะ (n + 2 - ((n + 2)% 3)) / 3 * 4 ไบต์ยาวดังนั้นจำนวนไบต์ที่ส่งออกต่อไบต์ที่นำเข้าจะแปลงเป็น 4/3 หรือ 1.33333 สำหรับ n ขนาดใหญ่

16kb * 4/3 ให้น้อยกว่า 21.3 'kb หรือ 21848 ไบต์น้อยมาก

หวังว่านี่จะช่วยได้


11

16kb คือ 131,072 บิต Base64 บรรจุบัฟเฟอร์ 24 บิตลงในตัวละคร 6 บิตสี่ตัวดังนั้นคุณจะมี 5,462 * 4 = 21,848 ไบต์


5

เนื่องจากคำถามเกี่ยวกับการเพิ่มขึ้นที่เลวร้ายที่สุดที่เป็นไปได้ฉันต้องเพิ่มว่าโดยปกติจะมีตัวแบ่งบรรทัดที่ประมาณ 80 อักขระแต่ละตัว ซึ่งหมายความว่าหากคุณบันทึกข้อมูลที่เข้ารหัส base64 ลงในไฟล์ข้อความบน Windows ระบบจะเพิ่ม 2 ไบต์บน Linux 1 ไบต์สำหรับแต่ละบรรทัด

การเพิ่มขึ้นของการเข้ารหัสที่แท้จริงได้อธิบายไว้ข้างต้น


3
ไม่ใช่กรณีที่สุดขีดที่ 1 ไบต์แหล่งที่มากลายเป็น 4 base64 ไบต์ดังนั้นเพิ่มขึ้น 4x? แหล่งข้อมูลที่ยาวขึ้นเรื่อย ๆ จะได้อัตราส่วนที่ดีกว่าจนกระทั่งอย่างที่คนอื่น ๆ บอกกันมันจะเข้าใกล้ asymptotically 1.333 ...
Olie

1

นี่คือการอ้างอิงในอนาคตสำหรับตัวเอง เนื่องจากคำถามอยู่ในกรณีที่เลวร้ายที่สุดเราควรคำนึงถึงตัวแบ่งบรรทัด ในขณะที่ RFC 1421 กำหนดความยาวบรรทัดสูงสุดเป็น 64 อักขระ, RFC 2045 (MIME) ระบุว่ามี 76 อักขระในหนึ่งบรรทัด

หลังคือสิ่งที่ห้องสมุด C # ได้ดำเนินการ ดังนั้นในสภาพแวดล้อม Windows ที่ตัวแบ่งบรรทัดเป็น 2 ตัวอักษร (\ r \ n) เราจะได้รับสิ่งนี้:Length = Floor(Ceiling(N/3) * 4 * 78 / 76)

หมายเหตุ: การปูพื้นเป็นเพราะในระหว่างการทดสอบของฉันด้วย C # หากบรรทัดสุดท้ายสิ้นสุดที่ 76 ตัวอักษรอย่างแน่นอนจะไม่มีการขึ้นบรรทัดใหม่

ฉันสามารถพิสูจน์ได้โดยใช้รหัสต่อไปนี้:

byte[] bytes = new byte[16 * 1024];
Console.WriteLine(Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks).Length);

คำตอบสำหรับ 16 kBytes ที่เข้ารหัสไปยัง base64 ด้วยสาย 76-char: 22422 ตัวอักษร

สมมติว่าใน Linux เป็นเช่นนั้นLength = Floor(Ceiling(N/3) * 4 * 77 / 76)แต่ฉันยังไม่ได้ทดสอบบนแกน. NET ของฉัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.