data · 7 دقائق قراءة

ما UTF-8 حقًّا، وما فائدة BOM

انتصر ترميز واحد، لسبب يستحقّ الفهم — ثم هناك العلامة ذات البايتات الثلاثة التي تصلح Excel وتربك كل ما عداه.

النصّ في ملف بايتات. لا بدّ لشيء أن يقرّر أي بايت يعني أي حرف، وطوال ثلاثين سنة تقريبًا قرّر كلٌّ على نحو مختلف — ترميز لكل منطقة، كلّها تستعمل قيم البايتات نفسها لمحارف مختلفة.

حلّ Unicode النصف الأول بإسناد رقم لكل محرف في كل نظام كتابة. ثم حلّ UTF-8 النصف الثاني باختيار كيفية كتابة تلك الأرقام بايتاتٍ، وفعلها على نحو جعل التبنّي شبه مجّاني.

فكرتان، تبقيان منفصلتين

Unicode فهرس. الحرف A هو 65، والألف العربية 1575، ورمز تعبيري في مكان ما فوق 128,000. أرقام فقط، بلا تخزين.

UTF-8 طريقة لتخزين تلك الأرقام. UTF-16 وUTF-32 طريقتان أخريان. الملف الموصوف بكلمة «Unicode» وحدها لم يخبرك بالشيء الذي تحتاجه لقراءته، ولهذا لا تنفع تلك الكلمة في قائمة ترميزات.

لماذا انتصر UTF-8

يستعمل بايتًا واحدًا لأول 128 محرفًا — مجموعة ASCII بالضبط، بقيم ASCII بالضبط.

أي أن كل ملف ASCII كان أصلًا ملف UTF-8، دون تغيير، وكل برنامج يتعامل مع ASCII ظلّ يعمل. لا شيء وجب تحويله ولا شيء وجبت إعادة كتابته يوم التحوّل. ذلك التوافق مع الماضي هو السبب كلّه في إزاحته للبدائل.

خارج ASCII يستعمل بايتين لمعظم كتابات أوروبا والشرق الأوسط، وثلاثة لمعظم الكتابات الآسيوية، وأربعة للرموز التعبيرية والكتابات الأندر. النص الإنجليزي في معظمه لا يكلّف شيئًا تقريبًا؛ والنص الصيني في معظمه يكلّف 50% أكثر ممّا كان سيكلّفه UTF-16، وتلك هي المقايضة التي قُبلت.

له أيضًا خاصّية تبقي المحلّلات على استقامتها: البايت الأول من المحرف يقول كم بايتًا يتبعه، فتستطيع القفز إلى وسط ملف وإيجاد حدّ المحرف التالي. UTF-16 لا يقدر على ذلك.

علامة ترتيب البايتات

UTF-16 يأتي بنكهتين تبعًا لأي طرف من الرقم ذي البايتين يأتي أولًا، فهو يحتاج علامة في أول الملف تقول أيّهما. تلك العلامة هي علامة ترتيب البايتات.

UTF-8 بايتاته مفردة، فلا ترتيب بايتات فيه ليُعلَّم. هو لا يحتاج واحدة.

حصل عليها مع ذلك، توقيعًا: البايتات الثلاثة EF BB BF، بمعنى «هذا الملف UTF-8». تبيّن أن ذلك مفيد فعلًا لصيغة بلا موضع تعلن فيه ترميزها — أي لـCSV.

لماذا يحتاجها Excel وتكرهها المحلّلات

انقر نقرة مزدوجة على ملف CSV بترميز UTF-8 بلا BOM في Excel فيتشوّه النص خارج ASCII، لأن Excel يفترض ترميزًا إقليميًّا قديمًا. أضف BOM فيُفتح سليمًا. هذه أنفع حقيقة منفردة في هذا المقال.

الثمن أن كل ما عداه يرى ثلاثة بايتات غير متوقّعة قبل المحرف الأول. المحلّل الذي يقرأ صف الترويسة يجد العمود الأول اسمه \uFEFFid بدل id، فيفشل البحث بخطأ يعرض سلسلتين تبدوان متطابقتين.

لهذا وُجد utf-8-sig: اقرأ به فتُزال العلامة؛ اكتب به فتُضاف. أما utf-8 المجرّد فيتركها وشأنها في الاتّجاهين.

فالقاعدة إذن عن الوجهة. الملف الذاهب إلى برنامج جداول يأخذ BOM؛ والذاهب إلى برنامج لا يأخذها. حين يكون الاثنين معًا، أضفها وأخبر البرنامج أن يتوقّعها.

الطلاسم، ولماذا يمكن استرجاعها

حين ترى أحمد أو café، تكون بايتات UTF-8 قد قُرئت ترميزًا أحادي البايت. كل محرف حقيقي صار المحرفين أو الثلاثة التي تعنيها بايتاته في ذلك النظام الآخر.

الجزء المهمّ: لم يُفقد شيء. البايتات على القرص صحيحة والقارئ مخطئ، فإخبار القارئ بالترميز الصحيح يستعيد النص تمامًا.

لا يصير غير قابل للاسترجاع إلا حين تُحفظ النسخة المشوّهة. عندها تصير المحارف الخاطئة هي المحتوى الحقيقي، ويعني التراجع عن ذلك عكسَ سوء التأويل بعينه — وهو ينجح حين تستطيع تحديده، لا غير ذلك.

قواعد عملية

أعلنه حيثما استطعت: <meta charset="utf-8"> أول شيء في ترويسة HTML، وcharset=utf-8 في ترويسة نوع المحتوى، وUTF-8 ترميزًا لقاعدة البيانات وللاتّصال.

في MySQL، استعمل utf8mb4 لا utf8. فالمسمّى utf8 مجموعة جزئية بثلاثة بايتات لا تستطيع تخزين الرموز التعبيرية ولا عدّة كتابات، وهو فخّ قديم.

لا تفترض أبدًا ترميز ملف أُرسل إليك. انظر فيه، أو اسأل.

الخلاصة

Unicode يرقّم المحارف؛ وUTF-8 يخزّن تلك الأرقام بايتاتٍ، مطابقًا لـASCII بايتًا ببايت في أول 128. BOM توقيع اختياري من ثلاثة بايتات يعتمد عليه Excel وتتعثّر به المحلّلات. الطلاسم خطأ قراءة لا تلف — إلى أن يحفظها أحد.

أسئلة

ما UTF-8؟

طريقة لتخزين النص بايتاتٍ. كل محرف له رقم يسنده إليه Unicode، وUTF-8 أحد أنظمة كتابة تلك الأرقام — ببايت واحد لمجموعة ASCII الأصلية، وبايتين إلى أربعة لكل ما عداها. هو ما يستعمله الويب كلّه تقريبًا.

ما UTF-8 مع BOM؟

علامة ترتيب البايتات ثلاثة بايتات (EF BB BF) في أوّل الملف تمامًا تقول «هذا UTF-8». UTF-8 لا يحتاجها تقنيًّا — فلا ترتيب بايتات فيه ليُعلَّم — لكن Excel يستعملها ليقرّر كيف يقرأ ملف CSV، فهي الفرق بين ملف يُفتح سليمًا بنقرة مزدوجة وملف يُفتح طلاسم.

ما utf-8-sig في Python؟

الشيء نفسه، مسمّى من الجهة الأخرى. القراءة بـutf-8-sig تزيل علامة ترتيب البايتات إن وُجدت؛ والكتابة بها تضيف واحدة. أما utf-8 المجرّد فيترك العلامة في موضعها عند القراءة، ولهذا يظهر محرف بلا تفسير في أول حقلك الأول.

لماذا يظهر نصّي هكذا أحمد أو ما يشبهه؟

بايتات UTF-8 قُرئت كأنها ترميز أحادي البايت. كل محرف حقيقي يصير المحرفين أو الثلاثة التي تعنيها بايتاته صدفةً في ذلك الترميز الآخر. لا شيء تلف — البايتات صحيحة والقارئ مخطئ — فإخبار القارئ بالترميز الصحيح يستعيده تمامًا.

هل UTF-8 هو Unicode نفسه؟

لا. Unicode يسند رقمًا لكل محرف؛ وUTF-8 إحدى طرق تحويل تلك الأرقام إلى بايتات. UTF-16 وUTF-32 طريقتان أخريان. قولك إن ملفًّا «Unicode» لا يقول كيف خُزّن، وذلك هو الجزء الذي يحتاج القارئ معرفته.

أدوات من هذا الدليل

المزيد من أدوات البيانات — كلّها تعمل في متصفّحك، ولا واحدة منها ترفع ملفًّا.