هل تختلف UTF-8 وUTF-16 وUTF-32 في عدد الأحرف التي يمكنهم تخزينها؟

StackOverflow https://stackoverflow.com/questions/130438

  •  02-07-2019
  •  | 
  •  

سؤال

تمام.أعلم أن هذا يبدو نموذجيًا "لماذا لم يكتف بالبحث في جوجل أو الذهاب إلى www.unicode.org والبحث عنه؟" سؤال، ولكن لمثل هذا السؤال البسيط لا تزال الإجابة بعيدة عني بعد التحقق من كلا المصدرين.

أنا متأكد تمامًا من أن أنظمة التشفير الثلاثة هذه تدعم جميع أحرف Unicode، لكني بحاجة إلى تأكيد ذلك قبل تقديم هذا الادعاء في العرض التقديمي.

السؤال مكافأة:هل تختلف هذه الترميزات في عدد الأحرف التي يمكن تمديدها لدعمها؟

هل كانت مفيدة؟

المحلول

لا، إنها ببساطة طرق تشفير مختلفة.جميعهم يدعمون ترميز نفس مجموعة الأحرف.

يستخدم UTF-8 ما بين بايت واحد إلى أربعة بايت لكل حرف اعتمادًا على الحرف الذي تقوم بترميزه.تأخذ الأحرف الموجودة ضمن نطاق ASCII بايتًا واحدًا فقط بينما تأخذ الأحرف غير العادية أربعة بايت.

يستخدم UTF-32 أربعة بايتات لكل حرف بغض النظر عن الحرف، لذلك سيستخدم دائمًا مساحة أكبر من UTF-8 لترميز نفس السلسلة.الميزة الوحيدة هي أنه يمكنك حساب عدد الأحرف في سلسلة UTF-32 عن طريق حساب البايتات فقط.

يستخدم UTF-16 بايتين لمعظم الأحرف، وأربع بايت للأحرف غير العادية.

http://en.wikipedia.org/wiki/Comparison_of_Unicode_encodings

نصائح أخرى

لا يوجد حرف Unicode يمكن تخزينه في ترميز واحد وليس في ترميز آخر.وذلك ببساطة لأن أحرف Unicode الصالحة قد تم تقييدها بما يمكن تخزينه في UTF-16 (الذي يتمتع بأصغر سعة من بين الترميزات الثلاثة).بمعنى آخر، UTF-8 وUTF-32 استطاع يمكن استخدامها لتمثيل نطاق أوسع من الأحرف من UTF-16، لكنها ليست كذلك.اقرأ لتفاصيل أكثر.

ترميز UTF-8

UTF-8 هو رمز متغير الطول.تتطلب بعض الأحرف بايتًا واحدًا، وبعضها يتطلب 2، وبعضها 3 وبعضها 4.تتم ببساطة كتابة البايتات لكل حرف واحدًا تلو الآخر كتدفق مستمر من البايتات.

في حين أن بعض أحرف UTF-8 يمكن أن يصل طولها إلى 4 بايت، فإن UTF-8 لا يمكن ترميز 2^32 حرفًا.انها ليست قريبة حتى.سأحاول شرح أسباب ذلك.

البرنامج الذي يقرأ دفق UTF-8 يحصل فقط على تسلسل من البايتات - كيف من المفترض أن يقرر ما إذا كانت البايتات الأربع التالية عبارة عن حرف واحد مكون من 4 بايت، أو حرفين كل منهما 2 بايت، أو أربعة أحرف كل منها 1 بايت (أو بعض التركيبة الأخرى)؟يتم ذلك بشكل أساسي من خلال تحديد أن بعض التسلسلات ذات البايت الواحد ليست أحرفًا صالحة، وأن بعض التسلسلات المكونة من بايتين ليست أحرفًا صالحة، وما إلى ذلك.عندما تظهر هذه التسلسلات غير الصالحة، فمن المفترض أنها تشكل جزءًا من ملف طويل تسلسل.

لقد رأيت مثالًا مختلفًا إلى حد ما على هذا، أنا متأكد:يطلق عليه الهروب.في العديد من لغات البرمجة تقرر أن \ لا يُترجم الحرف الموجود في الكود المصدري للسلسلة إلى أي حرف صالح في النموذج "المترجم" للسلسلة.عندما يتم العثور على \ في المصدر، فمن المفترض أن يكون جزءًا من تسلسل أطول، مثل \n أو \xFF.لاحظ أن \x عبارة عن تسلسل غير صالح مكون من حرفين، و \xF هو تسلسل غير صالح مكون من 3 أحرف، ولكن \xFF هو تسلسل صالح مكون من 4 أحرف.

في الأساس، هناك مقايضة بين وجود العديد من الشخصيات وامتلاك شخصيات أقصر.إذا كنت تريد 2^32 حرفًا، فيجب أن يبلغ طولها في المتوسط ​​4 بايت.إذا كنت تريد أن تكون جميع الأحرف 2 بايت أو أقل، فلا يمكنك الحصول على أكثر من 2^16 حرفًا.يوفر UTF-8 حلاً وسطًا معقولًا:الجميع أسكي يتم إعطاء الأحرف (ASCII من 0 إلى 127) تمثيلات ذات بايت واحد، وهو أمر رائع للتوافق، ولكن يُسمح بالعديد من الأحرف الأخرى.

مثل معظم الترميزات ذات الطول المتغير، بما في ذلك أنواع تسلسلات الهروب الموضحة أعلاه، فإن UTF-8 هو عبارة عن ترميز رمز لحظي.وهذا يعني أن وحدة فك التشفير تقرأ فقط بايتًا بايت وبمجرد وصولها إلى البايت الأخير من الحرف، فإنها تعرف ما هو الحرف (ويعلم أنه ليس كذلك بداية شخصية أطول).

على سبيل المثال، يتم تمثيل الحرف "A" باستخدام البايت 65، ولا يوجد أحرف ثنائية/ثلاثية/أربعة بايت تكون البايتة الأولى لها 65.وإلا فلن يتمكن جهاز فك التشفير من تمييز تلك الأحرف باستثناء الحرف "A" متبوعًا بشيء آخر.

لكن UTF-8 مقيد بشكل أكبر.إنه يضمن عدم ظهور ترميز الحرف الأقصر أبدًا في أى مكان ضمن ترميز حرف أطول.على سبيل المثال، لا يمكن أن يكون أي من البايتات في حرف مكون من 4 بايت 65.

نظرًا لأن UTF-8 يحتوي على 128 حرفًا مختلفًا كل منها 1 بايت (قيمها البايت هي 0-127)، فإن جميع الأحرف 2 و3 و4 بايت يجب أن تتكون فقط من بايتات في النطاق 128-256.هذا قيد كبير.ومع ذلك، فهو يسمح لوظائف السلسلة الموجهة بالبايت بالعمل مع تعديل بسيط أو بدون تعديل.على سبيل المثال، C strstr() تعمل الدالة دائمًا كما هو متوقع إذا كانت مدخلاتها عبارة عن سلاسل UTF-8 صالحة.

UTF-16

UTF-16 هو أيضًا رمز متغير الطول؛تستهلك أحرفها 2 أو 4 بايت.يتم حجز قيم 2 بايت في النطاق 0xD800-0xDFFF لإنشاء أحرف 4 بايت، وتتكون جميع الأحرف 4 بايت من بايتين في النطاق 0xD800-0xDBFF متبوعتين بايتتين في النطاق 0xDC00-0xDFFF.لهذا السبب، لا يقوم Unicode بتعيين أي أحرف في النطاق U+D800-U+DFFF.

يو تي إف-32

UTF-32 هو رمز ذو طول ثابت، حيث يبلغ طول كل حرف 4 بايت.بينما يسمح هذا بتشفير 2^32 حرفًا مختلفًا، إلا أنه يُسمح فقط بالقيم بين 0 و0x10FFFF في هذا المخطط.

مقارنة القدرات:

  • ترميز UTF-8: 2,097,152 (في الواقع 2,166,912 ولكن نظرًا لتفاصيل التصميم، فإن بعضها يشير إلى نفس الشيء)
  • ترميز UTF-16: 1,112,064
  • UTF-32: 4,294,967,296 (ولكن يقتصر على أول 1,114,112)

الأكثر تقييدًا هو UTF-16!لقد حد تعريف Unicode الرسمي من أحرف Unicode لتلك التي يمكن تشفيرها باستخدام UTF-16 (أي.النطاق U+0000 إلى U+10FFFF باستثناء U+D800 إلى U+DFFF).يدعم UTF-8 وUTF-32 كل هذه الأحرف.

نظام UTF-8 يقتصر في الواقع "بشكل مصطنع" على 4 بايت.يمكن تمديده إلى 8 بايت دون انتهاك القيود التي ذكرتها سابقًا، وهذا من شأنه أن يؤدي إلى سعة 2^42.في الواقع، سمحت مواصفات UTF-8 الأصلية بما يصل إلى 6 بايت، مما يعطي سعة 2^31.لكن آر إف سي 3629 يقتصر على 4 بايت، لأن هذا هو المقدار المطلوب لتغطية كل ما يفعله UTF-16.

هناك أنظمة ترميز Unicode أخرى (تاريخية بشكل رئيسي)، ولا سيما UCS-2 (والتي هي قادرة فقط على تشفير U+0000 إلى U+FFFF).

تدعم كل من UTF-8 وUTF-16 وUTF-32 المجموعة الكاملة من نقاط ترميز Unicode.لا توجد أحرف يدعمها واحد دون الآخر.

أما بالنسبة لسؤال المكافأة "هل تختلف هذه الترميزات في عدد الأحرف التي يمكن تمديدها لدعمها؟" نعم و لا.الطريقة التي يتم بها ترميز UTF-8 وUTF-16 تحد من إجمالي عدد نقاط الكود التي يمكن أن تدعمها إلى أقل من 2^32.ومع ذلك، لن يقوم اتحاد Unicode بإضافة نقاط رمز إلى UTF-32 لا يمكن تمثيلها في UTF-8 أو UTF-16.إن القيام بذلك من شأنه أن ينتهك روح معايير التشفير، ويجعل من المستحيل ضمان تعيين واحد لواحد من UTF-32 إلى UTF-8 (أو UTF-16).

أنا شخصياً أتحقق دائمًا مشاركة جويل حول Unicode والترميزات ومجموعات الأحرف عندما تكون في شك.

يمكن لجميع ترميزات UTF-8/16/32 تعيين جميع أحرف Unicode.يرى مقارنة ويكيبيديا لترميزات Unicode.

هذه المقالة آي بي إم قم بتشفير مستندات XML الخاصة بك بتنسيق UTF-8 مفيد جدًا، ويشير إلى أنه إذا كان لديك الخيار، فمن الأفضل اختيار UTF-8.الأسباب الرئيسية هي دعم الأدوات على نطاق واسع، ويمكن لـ UTF-8 ذلك عادة المرور عبر الأنظمة التي لا تعرف يونيكود.

من القسم ماذا تقول المواصفات في ال مقالة آي بي إم:

أصبح كل من W3C و IETF مؤخرًا أكثر صرا على اختيار UTF-8 أولاً ، أخيرًا ، وأحيانًا فقط.نموذج حرف W3C لـ World Wide Web 1.0:تنص الأساسيات ، "عند الحاجة إلى ترميز حرف فريد ، يجب أن يكون ترميز الأحرف UTF-8 أو UTF-16 أو UTF-32.يتوافق US-ASCII مع UTF-8 (سلسلة US-ASCII هي أيضًا سلسلة UTF-8 ، انظر [RFC 3629]) ، وبالتالي فإن UTF-8 مناسب إذا كان التوافق مع US-ASCII مطلوبًا. "في. الممارسة ، والتوافق مع الولايات المتحدة-ASCII مفيدة للغاية ، فهو مطلب تقريبا.يوضح W3C بحكمة ، "في المواقف الأخرى ، مثل واجهات برمجة التطبيقات أو UTF-16 أو UTF-32 قد تكون أكثر ملاءمة.تشمل الأسباب المحتملة لاختيار واحدة من هذه كفاءة المعالجة الداخلية وقابلية التشغيل البيني مع العمليات الأخرى. "

كما قال الجميع، يمكن لـ UTF-8 وUTF-16 وUTF-32 تشفير جميع نقاط كود Unicode.ومع ذلك، فإن متغير UCS-2 (يشار إليه أحيانًا عن طريق الخطأ باسم UCS-16) لا يمكنه ذلك, ، وهذا هو الذي تجده على سبيل المثال.في نظام التشغيل Windows XP/Vista.

يرى ويكيبيديا للمزيد من المعلومات.

يحرر: أنا مخطئ بشأن Windows، NT كان الوحيد الذي يدعم UCS-2.ومع ذلك، فإن العديد من تطبيقات Windows تفترض كلمة واحدة لكل نقطة رمز كما هو الحال في UCS-2، لذلك من المحتمل أن تجد أخطاء.يرى مقالة ويكيبيديا أخرى.(شكرا جيسون ترو)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top