المستوى: مبتدئ · وقت القراءة: حوالي 7 دقائق · تحتاج معرفة بسيطة بأي لغة برمجة
ليه اسمك بيظهر رموز غريبة زي "Ù…Ø±ØØ¨Ø§"؟ فهم الترميز وUTF-8 من الصفر
بعد المقال ده هتعرف بالظبط ليه النص العربي بيتحوّل أحيانًا لرموز غريبة، وهتقدر تصلّح المشكلة في دقيقة بدل ما تقعد ساعة تخبط. الحكاية كلها في كلمة واحدة: الترميز (encoding).
المشكلة باختصار
فتحت ملف CSV فيه أسماء عربية على Excel، فلقيت "أحمد" اتحولت لـ "Ø£ØÙ…د". أو خزّنت تعليق في قاعدة البيانات، ورجعلك مليان علامات استفهام. ده مش عطل في جهازك، وده مش فيروس. الاسم العلمي للظاهرة دي هو mojibake (موجيباكي)، وسببها واحد بالظبط: النص اتكتب بترميز، واتقرأ بترميز تاني.
الحكاية بمثال بسيط قبل الكلام العلمي
تخيّل إنك بتبعت رسالة سرية لصاحبك بشيفرة: كل رقم بيقابل حرف. أنت كتبت الرسالة بجدول شيفرة معيّن، ولفّيتها في ورقة. لو صاحبك فكّها بنفس الجدول اللي أنت استخدمته، هيقرأ الكلام مظبوط. لكن لو مسك جدول تاني مختلف، الأرقام نفسها هتترجم لحروف تانية خالص، وهيطلعله كلام مبهم.
الكمبيوتر بيعمل نفس الحاجة بالظبط. هو مش بيخزّن "حروف"، هو بيخزّن أرقام (بايتات). الترميز هو "جدول الشيفرة" اللي بيقول: الرقم ده يساوي الحرف ده. لو خزّنت بجدول UTF-8 وقريت بجدول latin-1، بتطلعلك رموز غريبة. نفس فكرة الرسالة السرية.
الكلام العلمي: من الحرف للبايت
أي حرف في الدنيا له رقم موحّد اسمه code point في معيار Unicode. الحرف A رقمه U+0041، وحرف الميم "م" رقمه U+0645. لكن الرقم ده لازم يتحوّل لبايتات عشان يتخزّن أو يتبعت في الشبكة. العملية دي اسمها encoding، وأشهر طريقة ليها هي UTF-8.
في UTF-8، الحروف الإنجليزية (ASCII) بتاخد بايت واحد لكل حرف، والحروف العربية بتاخد بايتين لكل حرف. عشان كده لما تقيس طول كلمة عربية بالبايت هتلاقيه ضعف عدد حروفها تقريبًا. جرّب بنفسك:
جرّبها بنفسك: 6 أسطر بايثون توريك المشكلة والحل
الكود ده بيوضح ليه mojibake بيحصل، وإزاي يترجع النص صح لما تستخدم نفس الترميز:
text = "مرحبا"
# encode: نحوّل النص لبايتات باستخدام UTF-8
data = text.encode("utf-8")
print(len(text), "حروف") # 5 حروف
print(len(data), "بايت") # 10 بايت (كل حرف عربي = بايتين)
# decode صح: بنفس الترميز
print(data.decode("utf-8")) # مرحبا ← رجع سليم
# decode غلط: بترميز تاني = mojibake
print(data.decode("latin-1")) # Ù…Ø±ØØ¨Ø§ ← رموز غريبة
ركز في النتيجة: نفس الـ 10 بايت بالظبط. الفرق الوحيد هو "الجدول" اللي قريت بيه. UTF-8 رجّع الكلمة، وlatin-1 حوّلها لرموز. المشكلة مش في البيانات، المشكلة في .