ทำไมสตริงที่เข้ารหัส base64 จึงมีเครื่องหมาย = ที่ส่วนท้าย


322

ฉันรู้ว่าการbase64เข้ารหัสคืออะไรและจะคำนวณการbase64เข้ารหัสใน C # ได้อย่างไร แต่ฉันได้เห็นหลายครั้งว่าเมื่อฉันแปลงสตริงเป็นเบส 64 จะมี=การสิ้นสุด

มีคำถามสองสามข้อที่เกิดขึ้น:

  1. ที่ไม่base64สตริงมักจะจบด้วย=?
  2. ทำไมการ=ได้รับต่อท้าย?

9
สิ่งนี้ไม่มีอะไรเกี่ยวข้องกับ C #
BoltClock

19
จริงๆแล้วมันเกี่ยวข้องกับ c # ไม่ใช่ทุกภาษาที่จะรวมถึง = ตัวอย่างเช่นไลบราห้องสมุดจำนวนมากละเว้น = ดังนั้นการรู้สภาพแวดล้อมที่ผู้ใช้ใช้นั้นมีความเกี่ยวข้องจริง ๆ
จาค็อบ

ดูเหมือนว่าสิ่งนี้จะทำให้วิธีการทำให้งงงวยมีประสิทธิภาพน้อยลงในบางกรณีเพราะสามารถตรวจจับได้
dgo

6
@ user1167442 Base64 ไม่ได้มีไว้สำหรับ obfuscation มันมีไว้สำหรับการขนส่งข้อมูลไบนารี (หรือสตริงที่มี Unicode และอักขระพิเศษอื่น ๆ ) เป็นสตริง
นิวแฮมป์เชียร์

คำตอบ:


270

มันทำหน้าที่เป็นช่องว่างภายใน

คำตอบที่สมบูรณ์มากขึ้นคือสตริงที่เข้ารหัส base64 ไม่ได้ลงท้ายด้วย a เสมอ=มันจะจบลงด้วยหนึ่งหรือสอง=ถ้าพวกเขาจะต้องรองสตริงออกให้มีความยาวที่เหมาะสม


3
"กรณีหนึ่งที่ต้องใช้อักขระการเติมช่องว่างคือการเชื่อมไฟล์หลายไฟล์ที่เข้ารหัส Base64"
André Puel

1
@ AndréPuel: ลองซิงเกิ้ล=ใหม่ต่อไป หากคุณต้องการหาขอบเขตกลับมาก็จะมี terminator อยู่เสมอ (และยังจำเป็นต้องมีเพียงถ่านเดียว) แนวคิดการขยายทั้งหมดของ Base64 เป็นเพียงความคิด ...
6502

5
แม้ว่าลิงก์นั้นไม่เกี่ยวข้องกับ base64 อย่างสมบูรณ์ก็ตาม
นิวแฮมป์เชียร์

1
ฉันแค่หวังว่าลิงก์ที่เกี่ยวข้องและเชื่อถือได้จะถูกโพสต์ซึ่งอธิบายเกี่ยวกับการขยายbase64อย่างมีประสิทธิภาพด้วยภาพประกอบและตัวอย่าง ลิงก์ปัจจุบันไปยังวิกิพีเดียไม่เกี่ยวข้องอย่างเช่น @NH กล่าวถึง
Fr0zenFyr

1
@ Fr0zenFyr หากคุณต้องการลิงค์en.wikipedia.org/wiki/Base64#Output_paddingค่อนข้างดี แต่คำตอบของ Badrเป็นคำตอบที่ดีกว่า (ยังไม่ได้ลงคะแนนเลย)
นิวแฮมป์เชียร์

313

1 ไม่มี

2- ในฐานะที่เป็นคำตอบสั้น ๆ : ตัวอักษร 65 ("=" เครื่องหมาย) ใช้เป็นส่วนประกอบในขั้นตอนสุดท้ายของการเข้ารหัสข้อความเท่านั้น

คุณจะไม่มีเครื่องหมาย '=' หากสตริงของคุณมีหลายตัวอักษร 3 ตัวเนื่องจากการBase64เข้ารหัสใช้เวลาสามไบต์ (8 บิต) และแสดงเป็นอักขระสี่ตัวที่พิมพ์ได้ในมาตรฐาน ASCII

รายละเอียด:

(a)ถ้าคุณต้องการเข้ารหัส

ABCDEFG <=> [ ABC] [ DEF] [G

Base64จะจัดการ (สร้างอักขระ 4 ตัว) กับบล็อกแรกและบล็อกที่สอง (เมื่อเสร็จสมบูรณ์) แต่สำหรับบล็อกที่สามจะเพิ่มสองเท่า==ในเอาต์พุตเพื่อให้อักขระที่ต้องการครบ 4 ตัวดังนั้นผลลัพธ์จะเป็น QUJD REVG Rw == (ไม่มีที่ว่าง)

(ข)ถ้าคุณต้องการเข้ารหัส ...

ABCDEFGH <=> [ ABC] [DEF ] [GH

ในทำนองเดียวกันมันจะเพิ่มเพียงหนึ่งเดียว=ในตอนท้ายของการส่งออกเพื่อให้ได้ 4 ตัวอักษรผลจะเป็น QUJD REVG R0g = (ไม่มีช่องว่าง)


26
นี่คือสมบูรณ์และชัดเจนกว่าคำตอบอื่น ๆ และแม้แต่ Wikipedia และควรได้รับคะแนนมากกว่าคำตอบที่ยอมรับซึ่งไม่ทำอะไรเลยนอกจากชี้ไปที่ลิงค์ wikipedia ขอชื่นชมคุณ! upvoted!
ANewGuyInTown

2
@AnewGuyIntown link วิกิพีเดียในโซลูชันที่ยอมรับไม่ถูกต้องไม่มีส่วนเกี่ยวข้องกับการเติมบน base64 หน้าที่ถูกต้องเชื่อมโยงโดยเลโกลัสในคำตอบ
Fr0zenFyr


66

จากWikipedia :

ลำดับ '==' สุดท้ายระบุว่ากลุ่มสุดท้ายมีเพียงหนึ่งไบต์และ '=' ระบุว่ามีสองไบต์

ดังนั้นนี่คือการเรียงลำดับบางอย่าง


16
  1. เลขที่
  2. เมื่อต้องการวางสตริงที่เข้ารหัส Base64 ให้มีความยาวหลายตัวอักขระ 4 ตัวเพื่อให้สามารถถอดรหัสได้อย่างถูกต้อง

3
ฉันลบ=ที่ท้ายและทดสอบสิ่งนี้สำหรับ 1 ล้านสาย การถอดรหัสจับคู่เสมอ
vivek_23

15

มันถูกกำหนดในRFC 2045เป็นอักขระการขยายพิเศษหากมีน้อยกว่า 24 บิตในตอนท้ายของข้อมูลที่เข้ารหัส


11

เครื่องหมายเท่ากับ (=) ใช้เป็นช่องว่างภายในในการเข้ารหัส base64 บางรูปแบบ บทความวิกิพีเดียใน base64 มีรายละเอียดทั้งหมด


2
คุณสามารถอธิบายเหตุผลของการที่ "==" คือ 1 ไบต์และ "=" คือ 2 ไบต์ได้หรือไม่ ฉันไม่เข้าใจ วิธีการป้อนข้อมูล: "มีความสุขทางกามารมณ์" จะได้รับผล "YW55IGNhcm5hbCBwbGVhc3VyZS4 =" ในขณะที่ "ความสุขทางกามารมณ์ใด ๆ " อาจได้รับผล
null

14
ไม่ใช่กรณีที่ '==' คือ 1 ไบต์และ '=' คือ 2 ไบต์ เป็นกรณีที่คุณต้องมีหลายไบต์ในสตริงทั้งหมดของคุณเสมอ ดังนั้นคุณจึงใช้สัญลักษณ์ '=' จนกว่าคุณจะได้รับสิ่งนั้น สตริงแรกมีอักขระหนึ่งตัวมากกว่าสตริงที่สองดังนั้นจึงจำเป็นต้องใช้ 'padding' = 'น้อยลงหนึ่งครั้ง
Sam Holloway

2
คำตอบนี้ควรจะเป็นความคิดเห็นหรือไม่?
Fr0zenFyr

9

มันคือช่องว่างภายใน จากhttp://en.wikipedia.org/wiki/Base64 :

ในทางทฤษฎีแล้วตัวอักขระการเติมไม่จำเป็นสำหรับการถอดรหัสเนื่องจากจำนวนไบต์ที่หายไปสามารถคำนวณได้จากจำนวนของตัวเลข Base64 ในการนำไปใช้งานบางตัวอักขระการบังคับใช้จำเป็นต้องมีในขณะที่สำหรับสิ่งอื่นนั้นไม่ได้ใช้ กรณีหนึ่งที่ต้องใช้อักขระการเติมช่องว่างคือการเชื่อมไฟล์หลายไฟล์ที่เข้ารหัส Base64


1
ส่วนที่เกี่ยวกับ "กรณีหนึ่งที่ต้องใช้อักขระการเติมช่องว่างคือการเชื่อมไฟล์ที่เข้ารหัส Base64 หลายไฟล์" มันผิด. ตัวอย่างเช่นเมื่อเชื่อมต่อสองไฟล์ base64 ซึ่งไบต์ต้นทางสำหรับแต่ละไฟล์คือ 3 ไบต์ยาวสตริงเบส 64 จะยาว 4 อักขระและไม่มีการเว้นวรรค เมื่อคุณต่อสตริง base64 ทั้งสองนี้เข้าด้วยกันจะไม่มีวิธีที่จะบอกได้ว่าใครเริ่มต้นหนึ่งและหยุดหนึ่งฐานบนสตริงที่ต่อกัน ดังนั้นการพึ่งพา base64 padding เพื่อช่วยในเรื่องนี้จะไม่ได้ผล ปัญหานี้จะมีอยู่สำหรับไฟล์ใด ๆ ที่มีความยาวไบต์หารด้วย 3 อย่างสม่ำเสมอ
Ron C

1
ฉันเดาว่าหมายถึงกรณีที่ผลลัพธ์สุดท้ายควรเป็นการต่อเชื่อมของอินพุต เช่นdecode(encode(A)+encode(B))=A+Bทำงานกับการเสริมกำลัง แต่ไม่ขาด
โทมัสลีโอนาร์ด

บางที แต่การใช้งานที่ จำกัด ดังกล่าวไม่อนุญาตให้ใช้อักขระตัวรองสำหรับกรณีทั่วไปของการแยกสตริงที่เข้ารหัสเมื่อสตริงที่เข้ารหัสถูกต่อกันเข้าด้วยกัน ฉันแค่พูดถึงมันเพื่อช่วยนักพัฒนาที่อาจคิดว่าพวกเขาสามารถใช้มันได้
Ron C

1
ฉันคิดว่าการคัดค้านของคุณเน้นให้เห็นถึงความแตกต่างระหว่างแนวคิดของการเติมเต็มและการกำหนดขอบเขต โดยทั่วไปผลลัพธ์ของการต่อข้อมูลไม่คาดว่าจะรวมข้อมูลที่เพียงพอเพื่อให้สามารถย้อนกลับได้ คุณจะไม่ทราบว่า "c3dpenpsZXJz" เดิมคือ "c3dpenps" + "ZXJz" หรือ "c3dpen" + "enpsZXJz" แต่คุณก็ไม่รู้เหมือนกันว่า "swizzlers" เดิมเป็น "swi" + "zzlers" หรือ "swizzl" + "ers"
GargantuChet

1
การคัดลอกความคิดเห็นของฉันจากคำตอบของการเติมเต็ม Base64ที่เกี่ยวข้อง:> การต่อข้อมูล Base64 [กับ '=' การเติมเต็ม] อนุญาตให้ผู้เข้ารหัสสามารถประมวลผลกลุ่มก้อนขนาดใหญ่แบบขนานโดยไม่ต้องรับภาระในการจัดเรียงขนาดก้อน ในทำนองเดียวกันในรายละเอียดการใช้งานอาจมีตัวเข้ารหัสที่ต้องการล้างข้อมูลบัฟเฟอร์ภายในที่มีขนาดไม่เท่ากับสามเท่า
อังเดร D

7

http://www.hcidata.info/base64.htm

การเข้ารหัส "Mary had" ถึง Base 64

ในตัวอย่างนี้เรากำลังใช้สตริงข้อความแบบง่าย ("Mary had") แต่หลักการนี้ไม่ว่าข้อมูลจะเป็นเช่นไร (เช่นไฟล์กราฟิก) ในการแปลงข้อมูลอินพุต 24 บิตเป็นเอาต์พุต 32 บิตการเข้ารหัส Base 64 จะแบ่ง 24 บิตเป็น 4 ชิ้นของ 6 บิต ปัญหาแรกที่เราสังเกตเห็นคือ "Mary had" ไม่ใช่หลายคูณ 3 ไบต์ - ยาว 8 ไบต์ ด้วยเหตุนี้กลุ่มบิตสุดท้ายจึงมีความยาวเพียง 4 บิต เพื่อแก้ไขปัญหานี้เราได้เพิ่ม '0' สองบิตพิเศษและจดจำความจริงนี้โดยการใส่ '=' ในตอนท้าย หากสตริงข้อความที่จะแปลงเป็นฐาน 64 มีความยาว 7 ไบต์กลุ่มสุดท้ายจะมี 2 บิต ในกรณีนี้เราจะได้เพิ่มสี่บิตพิเศษของ '0' และจำความจริงนี้โดยใส่ '==' ในตอนท้าย

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