เป็นไปได้หรือไม่ที่จะใช้ RegEx เพื่อตรวจสอบความถูกต้องหรือล้างข้อมูล Base64 นั่นเป็นคำถามง่ายๆ แต่ปัจจัยที่ผลักดันคำถามนี้คือสิ่งที่ทำให้ยาก
ฉันมีตัวถอดรหัส Base64 ที่ไม่สามารถพึ่งพาข้อมูลอินพุตเพื่อให้เป็นไปตามข้อกำหนด RFC ได้อย่างสมบูรณ์ ดังนั้นปัญหาที่ฉันพบคือปัญหาเช่นบางทีข้อมูล Base64 ที่อาจไม่ถูกแบ่งออกเป็น 78 (ฉันคิดว่ามันเป็น 78 ฉันต้องตรวจสอบ RFC อีกครั้งดังนั้นอย่าให้ฉันรู้ว่าตัวเลขที่แน่นอนไม่ถูกต้อง) เส้นหรือเส้นอาจไม่ลงท้ายด้วย CRLF ซึ่งอาจมีเพียง CR หรือ LF หรืออาจไม่มีก็ได้
ดังนั้นฉันจึงมีช่วงเวลาหนึ่งที่แยกวิเคราะห์ข้อมูล Base64 ที่จัดรูปแบบเช่นนี้ ด้วยเหตุนี้ตัวอย่างต่อไปนี้จึงไม่สามารถถอดรหัสได้อย่างน่าเชื่อถือ ฉันจะแสดงเฉพาะส่วนหัว MIME บางส่วนเพื่อความกะทัดรัด
Content-Transfer-Encoding: base64
VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu
โอเคการแยกวิเคราะห์จึงไม่มีปัญหาและเป็นผลลัพธ์ที่เราคาดหวัง และใน 99% ของกรณีการใช้รหัสใด ๆ อย่างน้อยเพื่อตรวจสอบว่าแต่ละถ่านในบัฟเฟอร์เป็นถ่าน base64 ที่ถูกต้องทำงานได้อย่างสมบูรณ์ แต่ตัวอย่างถัดไปจะโยนประแจลงในส่วนผสม
Content-Transfer-Encoding: base64
http://www.stackoverflow.com
VGhpcyBpcyBzaW1wbGUgQVNDSUkgQmFzZTY0IGZvciBTdGFja092ZXJmbG93IGV4YW1wbGUu
นี่เป็นเวอร์ชันของการเข้ารหัส Base64 ที่ฉันเคยเห็นในไวรัสและสิ่งอื่น ๆ ที่พยายามใช้ประโยชน์จากผู้อ่านอีเมลบางรายที่ต้องการแยกวิเคราะห์ละครใบ้โดยเสียค่าใช้จ่ายทั้งหมดเทียบกับที่ใช้ในหนังสืออย่างเคร่งครัดหรือมากกว่า RFC ถ้าคุณจะ.
ตัวถอดรหัส Base64 ของฉันถอดรหัสตัวอย่างที่สองเป็นสตรีมข้อมูลต่อไปนี้ และโปรดทราบว่าสตรีมดั้งเดิมคือข้อมูล ASCII ทั้งหมด!
[0x]86DB69FFFC30C2CB5A724A2F7AB7E5A307289951A1A5CC81A5CC81CDA5B5C1B19481054D0D
2524810985CD94D8D08199BDC8814DD1858DAD3DD995C999B1BDDC8195E1B585C1B194B8
ใครมีวิธีที่ดีในการแก้ปัญหาทั้งสองครั้ง ฉันไม่แน่ใจว่าจะเป็นไปได้ด้วยซ้ำนอกเหนือจากการทำการแปลงข้อมูลสองครั้งโดยใช้กฎที่แตกต่างกันและเปรียบเทียบผลลัพธ์ อย่างไรก็ตามหากคุณใช้แนวทางนั้นผลลัพธ์ใดที่คุณไว้วางใจ? ดูเหมือนว่า ASCII ฮิวริสติกเป็นวิธีแก้ปัญหาที่ดีที่สุดแต่โค้ดเวลาดำเนินการและความซับซ้อนจะเพิ่มเข้าไปในบางสิ่งที่ซับซ้อนพอ ๆ กับโปรแกรมสแกนไวรัสซึ่งรหัสนี้เกี่ยวข้องจริงหรือไม่? คุณจะฝึกเอนจินฮิวริสติกส์อย่างไรเพื่อเรียนรู้ว่า Base64 ยอมรับได้อย่างไรและอะไรไม่
อัพเดท:
เมื่อพิจารณาถึงจำนวนการดูคำถามนี้ยังคงได้รับฉันตัดสินใจโพสต์ RegEx แบบธรรมดาที่ฉันใช้ในแอปพลิเคชัน C # เป็นเวลา 3 ปีแล้วโดยมีธุรกรรมหลายแสนรายการ จริงๆแล้วฉันชอบคำตอบของGumbo มากที่สุดนั่นคือเหตุผลที่ฉันเลือกเป็นคำตอบที่เลือก แต่สำหรับทุกคนที่ใช้ C # และกำลังมองหาวิธีที่รวดเร็วอย่างน้อยที่สุดในการตรวจสอบว่าสตริงหรือไบต์ [] มีข้อมูล Base64 ที่ถูกต้องหรือไม่ฉันพบว่าสิ่งต่อไปนี้ทำงานได้ดีสำหรับฉัน
[^-A-Za-z0-9+/=]|=[^=]|={3,}$
และใช่นี่เป็นเพียงSTRINGของข้อมูล Base64 ไม่ใช่ข้อความRFC1341 ที่มีรูปแบบถูกต้อง ดังนั้นหากคุณกำลังจัดการกับข้อมูลประเภทนี้โปรดคำนึงถึงสิ่งนั้นก่อนที่จะพยายามใช้ RegEx ข้างต้น หากคุณกำลังจัดการกับ Base16, Base32, Radix หรือแม้แต่ Base64 เพื่อวัตถุประสงค์อื่น ๆ (URL, ชื่อไฟล์, การเข้ารหัส XML และอื่น ๆ ) ขอแนะนำให้คุณอ่านRFC4648ที่Gumboกล่าวถึงในคำตอบของเขาเนื่องจากคุณจำเป็นต้องเป็นอย่างดี ตระหนักถึงชุดอักขระและตัวยุติที่ใช้โดยการนำไปใช้ก่อนที่จะพยายามใช้คำแนะนำในชุดคำถาม / คำตอบนี้