ترميز الأحرف في الحاسوب
التعبير الأفضل هنا في الحقيقة هو "ترميز المحارف"، ﻷننا سنتحدث عن ترميز الحروف والرموز الرياضية ورموز العملات وغيرها، بالإضافة للأرقام نفسها (0-9). لذا، تعبّر كلمة محرف (character) عن الحرف والرمز والرقم.
وكما ذكرنا، يمكن إعطاء كل محرف قيمة عددية معينة، وهذا يعني في واقعه تشكيل معجم، حيث يتم ربط كل محرف بقيمته العددية الخاصة المعطاة، وعندما تضغط أنت على أحد المحارف في لوحة مفاتيحك، يتم النظر للمعجم وتحويله لقيمته الخاصة وتخزينها في الحاسوب (التحويل من محرف لقيمة عددية)، ثم عندما تريد طباعة ذلك المحرف على الشاشة، يتم النظر مجددًا للمعجم وتحويله من قيمته العددية المخزنة إلى الشكل الذي يمثله (التحويل من قيمة عددية لمحرف).
ولكن ما القيم التي نعطيها؟ أو بالأحرى كيف نبني ذلك المعجم؟ الحقيقة طريقة بناء المعجم تتوقف على المساحة التي لدينا، طبعًا من الأفضل دائمًا استخدام أقل مساحة ممكنة، ولكن ما هي أقل مساحة ممكنة؟ حسنًا لننظر ﻷحد المعاجم المقترحة والشائعة والتي تستخدم مساحة 7 بت لكل محرف.. لا ترتعب من مظهره العام، قد يبدو معقدًا، ولكن بتأمل بسيط ستجده أبسط مما يبدو عليه في الوهلة الأولى.
انظر مثلًا للعمود الأول من اليمين، وبتجاهل أول سطرين حاليًا، ستجد الأحرف p ثم q ثم r..وفي آخر هذا العمود بعض الرموز وزر DEL الموجود على لوحة مفاتيحك، حيث يجب تمثيل كل زر ورمز موجود على لوحة المفاتيح(الرموز التي يتم إدخالها مع الزر Shift كذلك). لذا ستجد في الخمس أعمدة التي تليه أي على يساره أيضًا المزيد من الأحرف اللاتينية والرموز. ثم يوجد عمودان يحويان محارف تسمى محارف التحكم (control characters). منها BEL (BELL) والذي يجعل حاسوبك يصدر صوتًا، و ESC (Escape) وغيرهم.
يسمى هذا الترميز (المعجم أعلاه) بـ "أسكي" (ASCII) والاسم هذا اختصار لـ American Standard Code for Information Interchange أي الكود المعياري الأمريكي لتبادل المعلومات، حيث بدأ العمل عليه منذ عام 1961، والجدول الذي تراه هو نسخة محدثة تم وضعها عام 1972.
ولكن لماذا صُمِّم الجدول بهذه الطريقة؟
يوجد عدة أسباب وأمور تمت مراعاتها في تصميم الجدول الذي رأيته في الأعلى، نذكر منها:
- لعرض جميع الاحتمالات للسبعة بت وبالتالي يظهر بشكل واضح أكبر عدد ممكن للمحارف التي نريد تمثيلها، أيُّ زيادةٍ على هذا الجدول تتطلب مساحة إضافية عن السبعة بت. (انظر الآن للأعمدة الأربعة الأولى من اليسار، والتي تمثل أول 4 بت، وقد أُعطوا فعلًا الأسماء b1 أي البت واحد ولغاية b4 أي البت الرابع من العدد، وانظر للسطر الأول الذي يمثل الثلاثة بت المتبقية من العدد ذو السبعة بت، وهم من b5 لغاية b7). مثال: إذا نظرنا للحرف A في الجدول، فيكون العدد الثنائي المقابل له هو البتات b7b6b5b4b3b2b1 يعني 1000001. ويمكن أن نضيف صفرًا على اليسار لنكمل الـ 8 بت.
- تمثيل الأرقام (0-9) (الظاهرين في العمود الخامس من اليمين وبدءًا من السطر الثالث) كما يتم تمثيلها بالفعل في النظام الثنائي بالنسبة للأربعة بت الأخيرة، مما يجعل التحويل من النظام الثنائي للعشري سهلًا.
- يظهر الفرق بين الأحرف بـ shift وبدون shift (العمود الأول مثلًا يبدأ بـ p و q، وإذا ضغطت على shift تحصل على القيم الموجودة في العمود الثالث حيث P كبيرة و Q وهكذا)
- تجميع الرموز مع بعضهم ومحارف التحكم مع بعضهم أيضًا، حيث تظهر محارف التحكم في أول 32 قيمة في جدول أسكي (الظاهرة يسارًا والتي تمثل 0-31 في النظام العشري)
كما تم مراعاة أنواع الترميز السابقة ﻷسكي، فقد تم وضع الحرف A في الموضع 41hex مراعاةً للمعايير البريطانية.
ولكن ما هي محارف التحكم؟
هي عبارة عن رموز خاصة ليست موضوعة لتشكل معلومات قابلة للطباعة (مثل الأحرف والأرقام والرموز)، وإنما للتحكم بالأجهزة التي تستخدم ترميز أسكي، مثل الطابعات. أو لإعطاء معلومات وصفية عن البيانات المرسلة والتي يتم تخزينها في الأقراص الصلبة. مثلًا، الحرف EOT اختصار لـ End of Text ويُستخدم في الأصل لإعطاء إشارة للحاسوب المستقبِل للبيانات أنه تم الانتهاء من إرسال السجل النصي الحالي، وقد يُستخدم ﻷغراض أخرى مثل إنهاء البرنامج أو العملية.
ليس بالضرورة اليوم أن يكون حاسوبك ونظام تشغيلك يستخدم ترميز أسكي أساسًا، فنحن نتحدث عن أول ترميز شائع، وليس الترميز الشائع اليوم. فقد استُخدم أسكي في البداية عام 1963 في أجهزة تلكس (شبيهة بالفاكس). وقد استُخدم في الحواسيب والوب بشكل شائع حتى عام 2007 حيث ظهرت أنواع ترميز أفضل منه.
فربما لاحظت أن الترميز هذا محدود جدًا؟ أين الأحرف العربية؟ وماذا عن الأحرف الصينية واليابانية والروسية والعبرية ولا أدري كم أبجدية تستخدم البشرية..ألا يجب ترميزها كلها؟
الموضوع فعلًا معقد، ففكر معي، لقد احتجنا 7 بت لترميز بعض الرموز و 26 حرف لاتيني كبير و 26 حرف صغير أي 52 بالمجمل. ولكن إذا أردنا إضافة 28 حرف عربي و 32 حرف روسي و 46 ياباني..إلخ. فكم بت سنحتاج؟!
ولكن لماذا لا يكون لكل لغة ترميزها الخاص؟ ألن يحل ذلك المشكلة؟
قد يحلها بشكل جزئي، ويوجد في الواقع ترميز خاص لليابانية مثلًا، وآخر خاص بالروسية، وترميز الأسكي الذي رأيته للتو الخاص بالإنجليزية. ولكنك تجد أنني أستخدم هنا الأحرف العربية والإنجليزية معًا في نص واحد، فإذا فُسِّر هذا النص وفق ترميز مخصص للغة واحدة فلن تظهر أحرف اللغة الأخرى كما يجب (قد تظهر على شكل إشارات استفهام أو طلاسم..وأعتقد أنك رأيت ذلك سابقًا في مكان ما).
لقد ذكرت لك أن ترميز أسكي يستخدم 7 بت فقط، إلا أن الحواسيب صُممت منذ البداية لتعمل مع وحدات من المساحة تكون 2 أس كذا، أي مضاعفات الاثنان، لذا توجّب إضافة 0 ليسار قيم الأحرف المرمزة بترميز أسكي لتصبح 8 بت (واحد بايت). وسمح كذلك هذا البت الزائد بإضافة أحرف جديدة، حيث تتسع الـ 7 بت لـ 127 محرف، بينما يوجد 128 خانة إضافية إذا استخدمنا ذلك البت الثامن. وشرع صانعوا الحواسيب مثل أبل وميكروسوفت و IBM بوضع تراميز موسعة للأسكي (Extended ASCII) عبر إضافة رموز وأحرف إضافية من اللغات الأوربية مثل Ä و Á وغيرها (مستغلين ذلك البت الثامن). وأنشأ كل مصنّع نسخ موسعة كثيرة خاصة به، وكل نسخة غير متوافقة مع الأخرى، وبدأت الفوضى، خاصة عند ظهور الوب وتبادل النصوص بين الأجهزة، فإذا تم إرسال النص المرمّز وفق ترميز معين لجهاز آخر وفُسّر وفق ترميز آخر، فلن يتم عرض النص بالشكل الصحيح. وسنرى الحل المقترح بعد قليل.
أحد تلك التراميز الموسعة هو ترميز CP-1252 والذي يدعى أيضًا windows-1252 بسبب استخدامه بشكل واسع في نظام ويندوز. يوسِّع هذا الترميز ترميز أسكي، حيث يستخدم أول سبعة بت كما يستخدمها أسكي (وبالتالي النصوص المُرمّزة وفق أسكي سيتعرف عليها بدون مشاكل) ويضيف لها بت إضافي، أي يستخدم 8 بت، لترميز الأحرف الإضافية الموجود في اللغات الأوربية مثل الإسبانية والفرنسية والألمانية، مثل الحرف ñ والحرفÜ وما إلى ذلك.
إذًا، استطاع الترميز الأخير توسيع ترميز أسكي وترميز باقي اللغات الأوربية عبر استخدام بت واحد إضافي أي 8 بت (وهذا يشكل بالمجمل بايت byte واحد). وهذا يعني في النظام العشري استخدام الأعداد من 0 إلى 255.
أما في الترميزات المتعلقة باللغات الكورية والصينية واليابانية فيتم استخدام 2 بايت أي 16 بت، وهذا يعني في النظام العشري المجال 0–65535 (على اعتبار استخدام الأعداد الموجبة فقط؛ أي عدم تخصيص بت للإشارة). وهي ترميزات مخصصة للغة معينة، أي لا يمكن أن تمثل الأحرف الإنجليزية مثلًا، ﻷنها تستخدم نفس القيم لإعطاء معاني أخرى خاصة بأحرفها، ومختلفة عما تعطيه قيم أسكي أو الترميزات الأخرى. مثال على ذلك: العدد 241 في النظام العشري يمثل الحرف الروسي Я وفق ترميز koi8-r، ونفس العدد يمثل الحرف اليوناني ώ وفق ترميز Mac Greek.
وقد عملت الترميزات المخصصة لكل لغة بشكل جيد قبل تطور الإنترنت، حيث احتاج كل شخص للعمل على حاسوبه فقط، وحيث يكون هو مؤلِّف النص، ويعيد فتح النص الذي كتبه بنفس البرنامج الذي يستخدم نفس الترميز، لذا لا يوجد أي مشكلة.
ولكن مع تطور الإنترنت، تخيل أن صديقك الكوري قام بإرسال رسالة لك بالبريد الإلكتروني (رسالة باللغة الإنجليزية مثلًا)، واستخدم ترميز معين غير الذي تستخدمه أنت في جهازك، عندها سيظهر لك نصًا عجيبًا، مؤلف من إشارات استفهام، أو أحرف غريبة تشكل طلاسم وشيفرات وراثية! 😁 ولا بد أنك رأيت مثل ذلك من قبل.
لنتذكر سبب المشكلة؛ مشكلة الخطأ في تفسير النص. حيث قام الشخص بكتابة نص باستخدام ترميز معين (معجم معين يعطي لكل حرف عدد مخصص له) وقد تم حفظ تلك الأعداد ونقلها إليك بالشكل الصحيح، فالأعداد التي تمثل النص والتي حُفظت بجهازه، قد تم نقلها نفسها لجهازك بدون أي خطأ، الخطأ الذي يحدث الآن هو أنك تستخدم ترميز (معجم) آخر لتفسير تلك الأعداد وعرضها بشكل نص، مما يؤدي لتفسير خاطئ للأعداد وإعطاء أحرف غير المتوقعة. وحل هذه المشكلة لا يستدعي أبدًا أن تطلب إعادة إرسال الملف النصي، فالمعلومات لديك بالفعل، بل أن تستخدم الترميز الصحيح لتفسير الملف.
والآن وبسبب وجود الإنترنت، نحتاج لترميز موحد لعرض النصوص على كل الأجهزة وفق نفس الترميز، وهذا يتطلب منا وجود ترميز يفسر كل الأحرف في كل اللغات، وذلك سيحل أيضًا مشكلة ترميز النص الذي يحوي بداخله كلمات من أبجديات مختلفة، مثل ما أفعل أنا هنا من خلال استخدام الأحرف العربية والإنجليزية في نفس النص.
ولهذا وُجد ترميز Unicode، اختصارًا لـ Universal code أي الكود العالمي، وهو ما نطلبه بالضبط – ترميز مُوحَّد لكل اللغات.
يمثل هذا الترميز كل الأحرف بكل اللغات! وذلك عبر استخدام مساحة 4 بايت (32 بت) لكل حرف! (لقد اتسعت جميع الأحرف التي تم تمثيلها في 21 بت فقط، ولكن الحواسيب تعمل بشكل أفضل مع المساحة التي تكون من مضاعفات العدد2 (2-4-8-16-32-64..) وكوننا تجاوزنا الـ 16 فالأفضل استخدام مساحة 32*، وكذلك لإمكانية إضافة أحرف جديدة في المستقبل، مثل الصور الرمزية emojis الجديدة التي تظهر بين الحين والآخر. وهذا يعني أننا نضيف أصفارًا على اليسار في المساحة المتبقية غير المستخدمة)
* (تستخدم بعض التراميز 24 بت أي 3 بايت، يعني أن هذا ممكن. ولكن الترميز الذي نتحدث عنه الآن تم تصميمه بحيث يعطي 32 بت أي 4 بايت لكل حرف)
لنتوقف هنا ونفكر في الأمر. تصور أننا نريد كتابة نصًا بالإنجليزية، النص نفسه كان يتطلب 7 بت وفق ترميز أسكي (مع 0 إضافي على اليسار لنشكل بايت – أي 8 بت)، والآن نفس النص سيتطلب 4 أضعاف تلك المساحة، أي الملف النصي (الإنجليزي) سيأخذ بذلك أربعة أضعاف المساحة على القرص الصلب وفق هذا الترميز، وهذا سيبطئ عملية إرسال واستقبال الملف عبر الإنترنت (سيأخذ مجددًا أربع أضعاف المدة التي كان يحتاجها مع ترميز أسكي). أليست هذه مصيبة! نعم لقد وحدنا الترميز ولكن الحجم أصبح كبيًرا جدًا.
لقد وُضع ترميز Unicode بحيث يكون متوافق مع أسكي، بسبب الاستخدام الواسع ﻷسكي في ذلك الوقت، وهذا يعني أنه يعطي نفس القيم للمحارف الموجودة في أسكي، وبالتالي يمكن عرض النصوص المرمزة بأسكي في هذا الترميز بدون مشاكل، ولكن الحجم أكبر كما ذكرنا، أي أن الحرف A مثلًا سيأخذ القيمة 01000001 في أسكي، ونفس القيمة في يونيكود ولكن مع إضافة أصفار على اليسار لإكمال الـ 32 بت:
00000000 00000000 00000000 01000001
هل رأيت الأصفار على اليسار، والتي يتجاوز عددها الثمانية؟ تتعامل الكثير من أنظمة التشغيل اليوم مع الثمانية أصفار المتعاقبة والمستقبَلة من جهاز آخر على أنها إشارة لانتهاء الإرسال، وبالتالي تتوقف عندها عن الاستقبال، وهذه مشكلة أخرى.
ولحل مشكلة المساحة الضائعة، تم اقتراح الترميز التالي، والذي يستخدم بشكل رئيسي 16 بت فقط، وبناءً على ذلك سُمي الترميز السابق بـ
UTF-32 (32-bit Unicode Transformation Format)
والترميز المقترح الذي سنتحدث عنه أُعطي الاسم UTF-16.
تُمثَّل القيم المعطاة من قبل ترميز يونيكود بالشكل U+ ثم القيمة وفق نظام العد الست عشري (hexadecimal)، وبهذا يُعطى مثلًا الحرف A القيمة U+0041 ويُعطي الرمز & القيمة U+0026 وهكذا (انظر لبعض الرموز وترميزها هنا https://home.unicode.org/ ويمكنك البحث في الرابط التالي عن ما تشاء، فيمكن أن تكتب أي حرف أجنبي أو عربي، أو تكتب اسم رمز معين مثل heart مثلًا لتظهر لك كل رموز القلب مع قيمها https://www.fileformat.info /info/unicode/char/search.htm ). وتسمى تلك القيم بـ code points وتكون جميع الرموز واﻷحرف تحمل القيم الواقعة في المجال بين U+0000 و U+10FFFF، أي 21 بت حد أقصى. وتقسم هذه القيم لـ 17 مستوى، حيث يشمل المستوى الأول جميع الأحرف المستخدمة في يومنا هذا، ويسمى Basic Multilingual Plane (BMP) وهو في المجال U+0000 إلى U+FFFF أي أول 16 بت.
لذا وكما رأيت، يمكن تمثيل كل الأحرف المستخدمة في لغات اليوم في 16 بت فقط، بل وحتى الصور الرمزية (emojis) ورموز الرياضيات والعلوم والموسيقا، وهذا مايفعله الترميز السابق UTF-32، أما المساحة الإضافية فهي للأحرف الأخرى الأقل استخدامًا (أو نادرة الاستخدام)، والتي تشمل مثلًا ما يسمى بالعربية الشمالية القديمة (Old North Arabian) وهي لغة أنا شخصيًا لم أسمع بها من قبل، انظر مثلًا لعينة من أحرفها.
حيث يمثل أول حرفين في الأعلى الحرف راء (على اليسار) والحرف تاء (على اليمين). وها نحن عرب ولا نستخدم هذه اﻷحرف أبدًا وفق ما أعلم، فلماذا نزيد المساحة من أجل أحرف لا تُستخدم إلا نادرًا..
هذا النص مجتزأ من المصدر: منصة القرويين التعليمية | مسار أسس علم الحاسوب
الحقوق: سُمح بنشره من قبل الكاتب