ข้อดีของการเลือกการเข้ารหัส ASCII ผ่าน UTF-8 คืออะไร


91

อักขระทั้งหมดใน ASCII สามารถเข้ารหัสได้โดยใช้ UTF-8 โดยไม่ต้องเพิ่มหน่วยความจำ (ทั้งคู่ต้องใช้หน่วยเก็บข้อมูลเป็นไบต์)

UTF-8 มีประโยชน์เพิ่มเติมจากการสนับสนุนอักขระนอกเหนือจาก "ASCII-characters" หากเป็นกรณีที่ว่าทำไมเราจะเคยเลือกการเข้ารหัส ASCII กว่า UTF-8?

มีกรณีการใช้งานเมื่อเราจะเลือก ASCII แทน UTF-8 หรือไม่?


9
เพื่อสนับสนุนสิ่งมรดก ...
fretje

9
ผมหมายถึง UTF8 เป็น legacily สนับสนุน ASCII เกินไป ดังนั้นแม้ว่าคุณจะต้องสนับสนุนสิ่งที่เป็นมรดก UTF8 จะทำงานได้ดีโดยไม่จำเป็นต้องทำการเปลี่ยนแปลงใด ๆ
Pacerier

3
บางทีคุณอาจต้องทำงานร่วมกับระบบที่บรรจุอักขระ ASCII 8 ตัวเป็น 7 ไบต์? ผู้คนทำสิ่งที่บ้าเพื่อให้เข้ากับสิ่งต่าง ๆ
Donal Fellows

4
เรียกฉันว่าถั่ว แต่ฉันจะบอกว่าปลอดภัยและมีเสถียรภาพ ชุดอักขระที่ไม่มีลำดับหลายไบต์ยากที่จะทำลายได้มาก อย่าเข้าใจฉันผิดเมื่อภาษามนุษย์เป็นสิ่งสำคัญ ASCII จะไม่ตัดมัน แต่ถ้าคุณเพียงแค่ทำการเขียนโปรแกรมพื้นฐานและสามารถบีบตัวเองเป็นภาษาพื้นเมืองคอมไพเลอร์และระบบปฏิบัติการถูกเขียนขึ้นมาทำไมต้องเพิ่มความซับซ้อน @ Donal Fellows ล่าสุดฉันตรวจสอบ ... ASCII คือ 7 ไบต์ (อะไรกับบิตพิเศษเพียงไม่ ASCII และถามปัญหา)
ebyrob

2
@ebyrob ฉันคิดว่า Donal Fellows หมายถึงบิตที่บรรจุสัญลักษณ์ 8 ASCII เป็น 7 ไบต์เนื่องจากแต่ละสัญลักษณ์ใช้ 7 บิตในแต่ละ ... 8 * 7 = 56 bits = 7 ไบต์ มันจะหมายถึงฟังก์ชั่นการเข้ารหัสและถอดรหัสพิเศษเพียงบันทึก 1 ไบต์ของที่จัดเก็บข้อมูลจากทุก ๆ 8
dodgy_coder

คำตอบ:


83

ในบางกรณีสามารถเพิ่มความเร็วในการเข้าถึงอักขระแต่ละตัวได้ ลองนึกภาพสายอักขระที่str='ABC'เข้ารหัสใน UTF8 และใน ASCII (และสมมติว่าภาษา / คอมไพเลอร์ / ฐานข้อมูลรู้เกี่ยวกับการเข้ารหัส)

ในการเข้าถึงสาม ( C) c = str[2]ตัวละครจากสายนี้ใช้ประกอบอาร์เรย์การเข้าถึงซึ่งเป็นจุดเด่นในหลายภาษาโปรแกรมที่คุณจะทำสิ่งที่ชอบ

ตอนนี้ถ้าสตริงเข้ารหัส ASCII ทั้งหมดที่เราต้องทำคือดึงข้อมูลไบต์ที่สามจากสตริง

หากสตริงถูกเข้ารหัส UTF-8 เราต้องตรวจสอบก่อนว่าอักขระตัวแรกเป็นอักขระหนึ่งหรือสองไบต์แล้วเราต้องทำการตรวจสอบอักขระตัวที่สองเหมือนกันและจากนั้นเราสามารถเข้าถึงอักขระที่สามได้ ความแตกต่างในการทำงานจะยิ่งใหญ่กว่าความยาวของสตริงจะยิ่งมากขึ้น

นี่เป็นปัญหาตัวอย่างในเอ็นจินฐานข้อมูลบางตัวซึ่งจะหาจุดเริ่มต้นของคอลัมน์ที่วางไว้ 'หลังจาก' VARCHAR ที่เข้ารหัส UTF-8 แล้วฐานข้อมูลไม่เพียง แต่ต้องตรวจสอบจำนวนอักขระที่มีในฟิลด์ VARCHAR แต่ยังรวมถึงวิธีการ หลายไบต์แต่ละคนใช้


3
ถ้าฐานข้อมูลไม่เก็บทั้ง "นับจำนวนตัวอักษร" และ "การนับไบต์" จากนั้นผมว่ามันมีปัญหาบางอย่าง ...
คณบดีฮาร์ดิ้ง

1
TBH ฉันรู้ว่าฐานข้อมูลที่จะเก็บทั้ง ... ไม่มี
Mchl

@Mchl: คุณคิดว่าฐานข้อมูลรู้ได้อย่างไรเมื่อถึงจุดสิ้นสุดของสตริง?
วินไคลน์

1
โดยปกติแล้วจะถึง 0x00 หรือ 0x0000
Mchl

4
@DeanHarding การนับจำนวนตัวละครจะบอกคุณได้อย่างไรว่าตัวละครตัวที่สองเริ่มต้นอย่างไร หรือฐานข้อมูลควรเก็บดัชนีสำหรับตัวละครแต่ละตัวด้วยหรือไม่ หมายเหตุ: มันไม่ได้เป็นเพียงแค่ 2 ตัวอักษร แต่อาจจะได้ถึง 4 (ยกเว้นกรณีที่เมื่อมัน 6) stackoverflow.com/questions/9533258/... (ผมคิดว่ามันเป็นเพียง UTF-16 ที่มีสิ่งที่น่าสะอิดสะเอียนนานจริงๆที่สามารถทำลายระบบของคุณ)
ebyrob

7

หากคุณจะใช้ชุดย่อย US-ASCII (หรือ ISO 646) ของ UTF-8 แสดงว่าไม่มีข้อได้เปรียบอย่างใดอย่างหนึ่ง ในความเป็นจริงทุกอย่างจะถูกเข้ารหัสเหมือนกัน

หากคุณกำลังจะไปไกลกว่าชุดอักขระ US-ASCII และใช้อักขระ (ตัวอย่าง) ด้วยเครื่องหมายเน้นเสียง umlauts ฯลฯ ที่ใช้ในภาษายุโรปตะวันตกโดยทั่วไปแล้วมีความแตกต่าง - สิ่งเหล่านี้ส่วนใหญ่ยังคงสามารถ ถูกเข้ารหัสด้วยไบต์เดียวใน ISO 8859 แต่จะต้องมีสองหรือมากกว่าไบต์เมื่อเข้ารหัสใน UTF-8 นอกจากนี้ยังมีข้อเสียแน่นอน: ISO 8859 กำหนดให้คุณใช้ย่านความถี่เพื่อระบุการเข้ารหัสที่ใช้และสนับสนุนเพียงหนึ่งของภาษาเหล่านี้ในแต่ละครั้ง ตัวอย่างเช่นคุณสามารถเข้ารหัสอักขระทั้งหมดของตัวอักษร Cyrillic (รัสเซีย, Belorussian ฯลฯ ) โดยใช้เพียงหนึ่งไบต์ต่อแอพ แต่ถ้าคุณต้องการ / ต้องการผสมกับอักขระภาษาฝรั่งเศสหรือสเปน (นอกเหนือจากที่อยู่ใน US-ASCII / ชุดย่อย ISO 646) คุณโชคไม่ดีเลยทีเดียว - คุณต้องเปลี่ยนชุดตัวละครให้สมบูรณ์

ISO 8859 มีประโยชน์สำหรับตัวอักษรยุโรปเท่านั้น เพื่อรองรับตัวอักษรส่วนใหญ่ที่ใช้ในตัวอักษรจีนญี่ปุ่นเกาหลีอาหรับ ฯลฯ คุณต้องใช้การเข้ารหัสที่แตกต่างกันอย่างสิ้นเชิง บางส่วนของสิ่งเหล่านี้ (เช่น Shift JIS สำหรับภาษาญี่ปุ่น) เป็นความเจ็บปวดที่ต้องจัดการ หากมีโอกาสที่คุณจะต้องการสนับสนุนพวกเขาฉันคิดว่ามันคุ้มค่าที่จะใช้ Unicode ในกรณีนี้


5

ANSI อาจมีหลายสิ่งส่วนใหญ่เป็นชุดอักขระ 8 บิตในเรื่องนี้ (เช่นรหัสหน้า 1252 ภายใต้ Windows)

บางทีคุณอาจคิดถึง ASCII ซึ่งเป็น 7 บิตและเซ็ตย่อยที่เหมาะสมของ UTF-8 เช่นสตรีม ASCII ที่ถูกต้องใด ๆ ก็เป็นสตรีม UTF-8 ที่ถูกต้องเช่นกัน

หากคุณกำลังคิดถึงชุดอักขระ 8 บิตข้อดีอย่างหนึ่งที่สำคัญอย่างหนึ่งก็คือว่าอักขระที่สามารถแทนได้ทั้งหมดนั้นเป็น 8 บิตอย่างแน่นอนโดยที่ UTF-8 สามารถมีได้ถึง 24 บิต


ใช่ฉันกำลังพูดถึงชุด ASCII ขนาด 7 บิต คุณคิดว่า 1 ข้อได้เปรียบที่เราจะต้องบันทึกบางสิ่งบางอย่างเป็น ascii แทน utf-8 หรือไม่? (ตั้งแต่ 7 บิตจะถูกบันทึกเป็น 8 บิตต่อไปขนาดไฟล์จะเหมือนกันทุก
ประการ

1
หากคุณมีอักขระที่ใหญ่กว่าค่า unicode 127 จะไม่สามารถบันทึกได้ใน ASCII

1
@Pacerier: สตริง ASCII ใด ๆ ที่เป็นสตริง UTF-8จึงมีไม่แตกต่างกัน ขั้นตอนการเข้ารหัสอาจเร็วกว่าขึ้นอยู่กับการแสดงสตริงของแพลตฟอร์มที่คุณใช้แม้ว่าฉันจะไม่คาดหวังว่าการเร่งความเร็วอย่างมีนัยสำคัญในขณะที่คุณสูญเสียความยืดหยุ่นอย่างมาก
back2dos

@Thor ที่เป็นเหตุผลว่าทำไมฉันถามว่าบันทึกเป็น ASCII มีข้อได้เปรียบในทุก ๆ
Pacerier

5
@Pacerier หากคุณบันทึก XML เป็น ASCII คุณต้องใช้เช่น & # 160; สำหรับพื้นที่ที่ไม่สามารถแตกหักได้ สิ่งนี้เติมได้มากกว่า แต่ทำให้ข้อมูลของคุณทนต่อข้อผิดพลาดการเข้ารหัส ISO-Latin-1 เทียบกับ UTF-8 ได้มากขึ้น นี่คือสิ่งที่เราทำในขณะที่แพลตฟอร์มพื้นฐานของเราทำเวทมนตร์ที่มองไม่เห็นด้วยตัวละครมากมาย การอยู่ใน ASCII ทำให้ข้อมูลของเราแข็งแกร่งยิ่งขึ้น

3

ใช่ยังมีบางกรณีการใช้งานที่ทำให้รู้สึก ASCII: รูปแบบไฟล์และโปรโตคอลเครือข่าย โดยเฉพาะอย่างยิ่งสำหรับการใช้งานที่:

  • คุณมีข้อมูลที่สร้างและใช้งานโดยโปรแกรมคอมพิวเตอร์โดยไม่แสดงให้ผู้ใช้เห็น
  • แต่มันมีประโยชน์สำหรับโปรแกรมเมอร์ที่จะสามารถอ่านเพื่อความสะดวกในการพัฒนาและการดีบัก

ด้วยการใช้ ASCII เป็นการเข้ารหัสของคุณคุณจะหลีกเลี่ยงความซับซ้อนของการเข้ารหัสแบบหลายไบต์ในขณะที่ยังคงสามารถอ่านได้โดยมนุษย์อย่างน้อยที่สุด

ตัวอย่างสองตัวอย่าง:

  • HTTPเป็นโปรโตคอลเครือข่ายที่กำหนดในแง่ของลำดับของ octet แต่มีประโยชน์มาก (อย่างน้อยสำหรับโปรแกรมเมอร์ที่พูดภาษาอังกฤษ) ซึ่งสิ่งเหล่านี้สอดคล้องกับการเข้ารหัส ASCII ของคำเช่น "GET", "POST", "ยอมรับภาษา" และ เป็นต้น
  • ชนิดก้อนในรูปแบบภาพ PNGประกอบด้วยสี่ octets แต่มันก็มีประโยชน์หากคุณกำลังเขียนโปรแกรมเข้ารหัสถอดรหัส PNG หรือว่าIDATหมายถึง "ข้อมูลภาพ" และPLTEหมายความว่า "จาน"

แน่นอนคุณต้องระวังว่าข้อมูลจะไม่ถูกนำเสนอต่อผู้ใช้ปลายทางเพราะหากข้อมูลนั้นปรากฏให้เห็น (เกิดขึ้นในกรณีของ URL) ผู้ใช้จะคาดหวังว่าข้อมูลนั้นจะถูกต้อง ในภาษาที่พวกเขาสามารถอ่านได้


พูดได้ดี. มันเป็นเรื่องน่าขันเล็ก ๆ น้อย ๆ ที่ HTTP ซึ่งเป็นโปรโตคอลที่ส่งยูนิโค้ดมากที่สุดบนดาวเคราะห์ดวงนี้ต้องการเพียงสนับสนุน ASCII เท่านั้น (อันที่จริงแล้วฉันคิดว่ามันจะเหมือนกันสำหรับ TCP และ IP, การสนับสนุนแบบไบนารี, การสนับสนุน ASCII ... นั่นคือทั้งหมดที่คุณต้องการในระดับของสแต็กนั้น)
ebyrob

2

ก่อนอื่น: ชื่อของคุณใช้ / d ANSI ในขณะที่อยู่ในข้อความที่คุณอ้างถึง ASCII โปรดทราบว่า ANSI ไม่เท่ากับ ASCII ANSI รวมชุด ASCII ไว้ แต่ชุด ASCII ถูก จำกัด ไว้ที่ 128 ตัวเลขแรก (0 - 127)

หากข้อมูลทั้งหมดของคุณถูก จำกัด ไว้ที่ ASCII (7 บิต) ไม่สำคัญว่าคุณจะใช้ UTF-8, ANSI หรือ ASCII เนื่องจากทั้ง ANSI และ UTF-8 รวมชุด ASCII ทั้งหมด กล่าวอีกนัยหนึ่ง: ค่าตัวเลข 0 ถึงและรวมถึง 127 แสดงถึงอักขระเดียวกันใน ASCII, ANSI และ UTF-8

หากคุณต้องการตัวละครนอกชุด ASCII คุณจะต้องเลือกการเข้ารหัส คุณสามารถใช้ ANSI แต่แล้วคุณพบปัญหาของหน้ารหัสที่แตกต่างกันทั้งหมด สร้างไฟล์บนเครื่อง A และอ่านบนเครื่อง B อาจ / จะสร้างข้อความที่ดูตลกหากเครื่องเหล่านี้ถูกตั้งค่าให้ใช้หน้ารหัสที่แตกต่างกันง่าย ๆ เพราะค่าตัวเลข nnn แสดงถึงอักขระที่แตกต่างในหน้ารหัสเหล่านี้

"code page hell" นี้เป็นเหตุผลที่กำหนดมาตรฐาน Unicode UTF-8 เป็นเพียงการเข้ารหัสมาตรฐานเดียวเท่านั้นยังมีอีกมากมาย UTF-16 เป็นที่ใช้กันอย่างแพร่หลายมากที่สุดเนื่องจากเป็นการเข้ารหัสดั้งเดิมสำหรับ Windows

ดังนั้นถ้าคุณต้องการที่จะสนับสนุนอะไรเกิน 128 ตัวอักษรชุด ASCII คำแนะนำของฉันคือการไปกับUTF-8 ด้วยวิธีนี้มันไม่สำคัญและคุณไม่ต้องกังวลกับหน้ารหัสที่ผู้ใช้ของคุณตั้งค่าระบบของพวกเขา


หากฉันไม่ต้องการรองรับเกิน 128 ตัวอักษรข้อดีของการเลือกการเข้ารหัส ACSII ผ่านการเข้ารหัส UTF8 คืออะไร
Pacerier

นอกจาก จำกัด ตัวคุณเองที่ 128 ตัวอักษร? ไม่มาก. UTF-8 ได้รับการออกแบบมาโดยเฉพาะเพื่อรองรับ ASCII และภาษาตะวันตกส่วนใหญ่ที่ "เพียง" ต้องการ ANSI คุณจะพบว่า UTF-8 จะเข้ารหัสอักขระ ANSI ที่สูงกว่าจำนวนเล็กน้อยโดยมีมากกว่าหนึ่งไบต์ มีเหตุผลส่วนใหญ่ของหน้า HTML ที่ใช้ UTF-8 เป็นค่าเริ่มต้นคือ ...
Marjan Venema

1
@Pacerier หากคุณไม่ต้องการการเข้ารหัสที่สูงกว่า 127 การเลือก ASCII อาจคุ้มค่าเมื่อคุณใช้ API เพื่อเข้ารหัส / ถอดรหัสเนื่องจาก UTF ต้องการการตรวจสอบบิตเพิ่มเติมเพื่อพิจารณาไบต์เพิ่มเติมตามอักขระตัวเดียวกันอาจต้องใช้การคำนวณเพิ่มเติมแทน pure ASCII ซึ่งเพิ่งอ่าน 8 บิตโดยไม่มีการตรวจสอบ แต่ฉันขอแนะนำให้คุณใช้ ASCII หากคุณต้องการการเพิ่มประสิทธิภาพในระดับสูงในการคำนวณขนาดใหญ่ (ใหญ่มาก) และคุณรู้ว่าคุณกำลังทำอะไรในการเพิ่มประสิทธิภาพนั้น ถ้าไม่ใช่เพียงแค่ใช้ UTF-8
Luciano
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.