محوّل النص إلى ست عشري

حوّل النص إلى ست عشري — بايتاته في UTF-8 أو UTF-16، مفصولة بمسافات أو مصفوفةً أو تسلسلات هروب أو تفريغًا — والست عشري إلى نص من جديد بأيٍّ من هذه الصور.

الإدخال
الإخراج
D9 85 D8 B1 D8 AD D8 A8 D8 A7

السلسلة على هيئة البايتات التي تُخزَّن فيها

كل سلسلة يتعامل معها برنامج هي في باطنها صفّ من البايتات، وهذه الصفحة تكتبها بالست عشري، رقمين لكل بايت. اكتب Hello فتحصل على ‎48 65 6C 6C 6F، بايت لكل حرف ومسافة بعد كل واحد منها إلا الأخير. وإذا ضبطت الاتجاه بدلًا من ذلك على «ست عشري إلى نص» وألصقت أرقامًا ست عشرية من سجل أو قاعدة بيانات أو أداة تنقيح، استعدت النص الذي تحمله تلك البايتات.

النص الواحد يصير بايتات مختلفة في ترميزات مختلفة، والوحدة هي التي تقرّر ما تكونه الأرقام في هذه الصفحة. وهي تبدأ على UTF-8، ترميز الويب، حيث H هو البايت 48 والحرف א هو البايتان D7 90. أما UTF-16 LE وUTF-16 BE فيصرفان بايتين على كل منهما، بترتيبين متعاكسين — ‎48 00 أو ‎00 48 للحرف H — بينما تستغني «نقاط الترميز» عن البايتات تمامًا وتكتب العدد الذي يسنده يونيكود، U+05D0 للحرف א. وأي وحدة مضبوطة تسري على الست عشري الذي تقرؤه كما تسري على النص الذي تكتبه، وتبقى مضبوطة: فإذا شابه الست عشري الملصوق ست عشري وحدة أخرى، قد تقترح الصفحة تلك الوحدة، لكن نقرتك وحدها هي التي تغيّرها.

رقمان ست عشريان لكل بايت

يحمل البايت قيمة من 256 قيمة، من 0 إلى 255. والست عشري يعدّ بالأساس ستة عشر، بالأرقام من 0 إلى 9 ثم بالحروف من A إلى F للعشرة حتى الخمسة عشر، وستة عشر مضروبة في ستة عشر تساوي 256، فرقمان ست عشريان يسمّيان كل بايت ولا حاجة أبدًا إلى رقم ثالث: 00 هو 0، و7F هو 127، وFF هو 255. والحرف H هو 72، أي أربع مرات ستة عشر وثمانية، فبايته 48.

كل رقم ست عشري يمثّل أربعة بتات بالضبط، أي نصف بايت: فالرقم 4 في 48 هو 0100، والرقم 8 هو 1000، وإذا وُضعا جنبًا إلى جنب كانا بتات H الثمانية، 01001000. والصفحة تُبقي رقمَي كل بايت كليهما، فتغذية السطر هي 0A والمسافة 20، ولأن كل بايت يأخذ العرض نفسه، يمكن قراءة الست عشري من جديد دون أي شيء بين البايتات: 4869 هي Hi.

والحروف في الست عشري تعني الشيء نفسه بالحالتين. والصفحة تكتب أحرفًا كبيرة ما لم تختر «أحرف صغيرة»، فيكون الحرف é هو C3 A9 أو c3 a9، وهي تقرأ الاثنين، حتى لو اختلطا في لصقة واحدة.

خمسة أنماط، كل منها مصوغ للمكان الذي يُلصق فيه

في الست عشري، يرتّب مُحدِّد «النمط» البايتات نفسها بخمس طرق، كل منها لمكان يذهب إليه الست عشري بعد ذلك. فللكلمة Hi، أي البايتين 48 و69:

  • «مفصول بمسافات» يعطي ‎48 69، بمسافة بين البايتات: الأسهل للقراءة والعدّ، والنمط الذي تُفتح عليه الصفحة.
  • «متصل» يعطي 4869، والأرقام متلاصقة، لحقل أو مُعامِل يأخذ القيمة سلسلةً واحدة من الأرقام الست عشرية.
  • «مصفوفة» يعطي 0x48, 0x69، كل بايت عدد قبله 0x وبين كل بايتين فاصلة، جاهزًا للصق في مصفوفة بايتات في C أو C#‎ أو JavaScript أو Python أو Go.
  • «تسلسلات هروب» يعطي ‎\x48\x69، كل بايت على هيئة ‎\x ورقميه، على نحو ما يُكتب البايت داخل سلسلة في C أو داخل سلسلة بايتات حرفية في Python مثل b'\x48\x69'‎.
  • «تفريغ ست عشري» يوزّع البايتات على أسطر، مع موضع بدء كل سطر والبايتات نفسها نصًا بجانبها: والقسم التالي يقرأ واحدًا منها.

والقراءة تستعيد الخمسة كلها، ومعها تنسيقات أخرى لا تمسّ البايتات: النقطتان كما في 48:69، والشرطات التي يكتبها BitConverter.ToString في ‎.NET، كما في ‎48-69، و0x أو 0X قبل كل بايت، ولفّ اللصقة كلها مرة واحدة بأقواس هلالية أو مربعة أو متعرجة، أو بعلامات اقتباس. والنمط وحالة الأحرف لا يهمّان إلا في الكتابة، فيختفي المُحدِّدان كلاهما حين يكون الاتجاه «ست عشري إلى نص».

وفي النمط «تسلسلات هروب» فخّ واحد. ففي سلسلة JavaScript، أو في سلسلة Python عادية لا في سلسلة بايتات حرفية، تسمّي ‎\x محرفًا لا بايتًا، فتكون ‎\xD7\x90 هناك محرفين لا الحرف א الذي بايتاه في UTF-8 هما D7 90. وبعد ASCII، أعطِ البايتات لما يأخذ بايتات.

قراءة تفريغ ست عشري، عمودًا عمودًا

التفريغ الست عشري يوزّع البايتات ستة عشر في كل سطر، مع عمود على كل جانب يساعدك على إيجادها. وإذا كُتب Hello, World!‎ وتغذية سطر في النمط «تفريغ ست عشري» ملآ سطرًا واحدًا: أولًا 00000000، الإزاحة، وهي موضع أول بايت في السطر معدودًا من الصفر، بثمانية أرقام ست عشرية؛ ثم البايتات الأربعة عشر، ثمانية ثم ستة، وبين النصفين فجوة أوسع؛ ثم ‎|Hello, World!.|‎، البايتات نفسها محارفَ، وكل بايت ليس من محارف ASCII القابلة للطباعة يظهر نقطةً، وتغذية السطر منها. ويحمل سطر أخير 0000000E وحده، أي أربعة عشر: الموضع الذي كان البايت التالي سيقع فيه، ومن ثم الطول. وهذا هو التخطيط الذي يطبعه hexdump -C.

  • إذا اخترت «ست عشري إلى نص» وأي وحدة غير «نقاط الترميز»، قُرئ التفريغ الست عشري الملصوق من أجل بايتاته وحدها: يبقى عمود النص خارج القراءة، ولا تُقرأ أي إزاحة على أنها بايت، ويقول تنبيه تحت النتيجة إن الإدخال أُخذ تفريغًا ست عشريًا ويسمّي التخطيط.
  • ويُقرأ بهذه الطريقة تخطيطان: تخطيط hexdump -C، وما يطبعه xxd بلا خيارات، حيث تتبع كلَّ إزاحة نقطتان وتقف البايتات في مجموعات من أربعة أرقام. أما الست عشري المجرد الذي يطبعه xxd -p فلا يحتاج إلى تخطيط ويُقرأ كأي ست عشري آخر.
  • يطبع hexdump -C سطرًا ليس فيه إلا * مكان الأسطر التي تكرر السطر الذي فوقها، وتملأ الصفحة تلك الأسطر من جديد انطلاقًا من الإزاحة التي تحتها، فتعود البايتات كاملة.
  • كل إزاحة بعد الأولى يجب أن تنبع من البايتات التي فوقها، ومنها الطول في السطر الأخير من hexdump -C، والسطر الذي لا تنبع إزاحته منها يُرفض هناك بدل أن يُقرأ قراءة خاطئة: وهناك يظهر السطر المحذوف أو البايت الضائع أو الإزاحة المكتوبة خطأً. وما لا تأتي بعده إزاحة لا يمكن التحقق منه، فالتفريغ الست عشري الذي تنقصه أسطره الأولى، أو نهاية تفريغ لا يليها سطر طول — وxxd لا يكتب سطرًا كهذا — يُقرأ على أنه ما تبقّى منه.

UTF-16 LE، ولماذا كل بايت ثانٍ هو 00

يحفظ Windows النص بترميز UTF-16 والبايت الأدنى أولًا، وهذا هو UTF-16 LE؛ وهو في ‎.NET يُسمّى Encoding.Unicode، ويخزّن SQL Server قيمة NVARCHAR بالطريقة نفسها. ويعطي UTF-16 كل محرف حتى U+FFFF بايتين، ولكل ما يصل إلى U+00FF — الحروف الإنجليزية والأرقام وé وسائر Latin-1 — يكون البايت الأعلى 00. ولأن البايت الأدنى يأتي أولًا، يقع ذلك الصفر بعد كل حرف: فالكلمة Hi هي ‎48 00 69 00.

يعرض SQL Server قيمة VARBINARY على هيئة 0x ثم أرقامها الست عشرية، فقيمة NVARCHAR التي تحمل Hi، إذا حُوّلت إلى VARBINARY، تظهر على هيئة 0x48006900. الصقها هنا وUTF-8 مختار، فيخرج النص H ثم NUL ثم i ثم NUL، ويقول التنبيه تحته إن كل بايت ثانٍ هو 00، كما يكون حين يُكتب نص بالأبجدية اللاتينية في UTF-16 لا في UTF-8، وبجانبه الزر «التبديل إلى UTF-16 LE». اضغطه فتُقرأ البايتات نفسها Hi.

أما UTF-16 BE فيضع البايت الأعلى أولًا، فتكون Hi هناك ‎00 48 00 69، ويكون الحرف א، وهو D0 05 في UTF-16 LE، هناك ‎05 D0. والأصفار في الموضع الأول من كل زوج تجعل التنبيه يقترح UTF-16 BE. ولا يقول شيئًا متى كان في النص محرف بعد U+00FF، لأن البايت الأعلى لذلك المحرف ليس 00، وهو لا يتكلم إلا حيث يكون كل بايت ثانٍ 00.

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

يمكن أن يبدأ النص بالمحرف U+FEFF، وهو محرف لا يُظهر شيئًا ووجوده ليكون علامة ترتيب البايتات. وفي UTF-16 يحدد بايتاه ترتيب كل زوج بعدهما، FF FE في UTF-16 LE وFE FF في UTF-16 BE، أما في UTF-8 فهو البايتات الثلاثة EF BB BF، وهي علامة مميِّزة تدل على أن النص UTF-8، الذي ليس له إلا ترتيب واحد.

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

بايتات ليست نصًا، تُعرض على هيئة U+FFFD

ليس كل تسلسل من البايتات نصًا في الوحدة المختارة: فالمحرف الذي ينقصه بايته الأخير، والبايت الشارد مثل E9، الذي تكتبه صفحات الترميز القديمة للحرف é، والبايت الزائد الباقي في آخر UTF-16، كلها لا تعني شيئًا. لكن تسلسلًا فاسدًا واحدًا لا يُفسد اللصقة كلها: إذ يحلّ محلّ كل واحد منها U+FFFD، أي حرف الاستبدال، ويُقرأ كل ما عداه على نحو طبيعي.

ثم يذكر تنبيه عددها ويسمّي أولها بموضعه بين البايتات، وبالأرقام التي كتبتها له، وبسطره وعموده. فالكلمة Café محفوظةً بترميز Windows-1252، صفحة ترميز Windows للنصوص الأوروبية الغربية، هي ‎43 61 66 E9، إذ é هناك بايت واحد هو E9؛ وإذا قُرئت على أنها UTF-8 عادت Caf وU+FFFD، ويسمّي التنبيه البايت 4، المكتوب E9، في السطر 1، العمود 10. أما في UTF-8 فالكلمة هي ‎43 61 66 C3 A9.

وهو يعدّ التسلسلات لا البايتات: فالبايتات F0 9F 98، وهي ثلاثة من بايتات 😀 الأربعة، هي U+FFFD واحد. أما U+FFFD الموجود فعلًا في النص، أي البايتات EF BF BD، فيُقرأ نصًا ولا يُعدّ أصلًا، فالتنبيه لا يتعلق إلا بالبايتات التي لم تُقرأ.

تحويل الست عشري إلى ملف من جديد

والقراءة تسلّمك البايتات كما تسلّمك النص. فحين يكون الاتجاه على «ست عشري إلى نص» ويكون UTF-8 أو UTF-16 LE أو UTF-16 BE مختارًا، يحفظ الزر «تنزيل» في ملف اسمه bytes.bin البايتاتِ التي قُرئت بالضبط، ومنها ما لم يكن نصًا، وقبل أن يُستبدل أي منها: وهذا هو العمل الذي يؤديه xxd -r مع التفريغ الست عشري. ولا «تنزيل» لنقاط الترميز، وهي ليست بايتات، ولا أثناء الكتابة، حين يكون ما تأخذه معك أرقامًا.

وهكذا يعود الست عشري لشيء لم يكن نصًا قط كاملًا مع ذلك. فكل صورة PNG تبدأ بالبايتات الثمانية ‎89 50 4E 47 0D 0A 1A 0A؛ وإذا قُرئت على أنها UTF-8 ظهرت على هيئة U+FFFD والحروف PNG وأربعة محارف تحكم، مع تنبيه عن التسلسل الواحد الذي ليس نصًا، ويحفظ الزر «تنزيل» الثمانية كلها بالضبط. واسم الملف دائمًا bytes.bin، لأن البايتات لا تحمل اسمًا، فأعطه اسمه الخاص، مثل image.png، بعد حفظه.

إلى أين تذهب من أجل محرف، أو بتاته، أو عدد

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

ومحوّل النص إلى ثنائي هو هذه الصفحة نفسها حين تُفتح على الثنائي، حيث يمكن قراءة القالب الذي يتبعه UTF-8 في البتات الأولى من كل بايت. والعدد ليس نصًا: إذا أُدخل 255 هنا فهو الأرقام 2 و5 و5، ومن ثم البايتات ‎32 35 35، بينما يأخذ محوّل أنظمة العد 255 على أنه كمية ويكتبه بالست عشري ff.

الأسئلة الشائعة

كيف أحوّل الست عشري إلى نص؟
اختر «ست عشري إلى نص»، والصق الأرقام الست عشرية، واضبط الوحدة لتطابق الترميز الذي كُتبت به: UTF-8 لمعظم النصوص، وUTF-16 LE للست عشري المأخوذ من سلسلة في Windows أو في ‎.NET أو من عمود NVARCHAR. والمسافات والفواصل والنقطتان والشرطات بين البايتات، و0x أو ‎\x قبلها، وغلاف واحد حول الكل، كلها مقبولة في القراءة، وكذلك حالة الأحرف أيًّا كانت.
لماذا يوجد NUL بين كل حرفين من نصي؟
على الأرجح أن الست عشري UTF-16 LE قُرئ على أنه UTF-8. إذ يكتب UTF-16 LE كل حرف إنجليزي بايتين، قيمته في ASCII ثم 00، ويقرأ UTF-8 كل صفر من تلك الأصفار محرفًا قائمًا بذاته، NUL. اختر UTF-16 LE، أو اضغط زر التبديل إن عرضته الصفحة بجانب تنبيهها، فتتلاصق الحروف من جديد.
لماذا تخرج الحروف ذات العلامات في الست عشري الخاص بي على هيئة U+FFFD؟
على الأرجح أن الست عشري كُتب بصفحة ترميز قديمة مثل Windows-1252، حيث é بايت واحد هو E9، بينما é في UTF-8 هو C3 A9 وE9 وحده ليس نصًا. والصفحة تقرأ UTF-8 وUTF-16 ولا تقرأ أي صفحة ترميز قديمة، فبدل أن تخمّن أيها كان المقصود، تعرض كل تسلسل كهذا على هيئة U+FFFD وتقول أين يقع أولها. ولا يزال الزر «تنزيل» يعطيك البايتات كما كانت.
هل أستطيع لصق ما طبعه xxd أو hexdump -C؟
نعم: تخطيط hexdump -C، وهو أيضًا ما يكتبه النمط «تفريغ ست عشري»، وما يطبعه xxd بلا خيارات. ويُترك عمود النص جانبًا ولا تُقرأ أي إزاحة على أنها بايت، ويُملأ سطر * من جديد، ويقول تنبيه أي التخطيطين قُرئ؛ والإزاحة التي لا تنبع من البايتات التي قبلها توقف القراءة عند سطرها، لأن الأسطر لم يعد بعضها يتفق مع بعض. ويُقرأ كذلك الست عشري المجرد الذي يطبعه xxd -p، كأي ست عشري آخر، بلا تنبيه.
هل يهم أن يكون الست عشري بأحرف كبيرة أو صغيرة؟
لا يهم البايتات: إذ إن 4A و4a هما البايت نفسه، J. والصفحة تكتب أحرفًا كبيرة ما لم تختر «أحرف صغيرة»، وهذا الاختيار يشمل إزاحات التفريغ الست عشري كما يشمل بايتاته؛ والقراءة تقبل الحالتين، حتى لو اختلطتا في لصقة واحدة.
كيف أستعيد ملفًا من تفريغ ست عشري؟
اختر «ست عشري إلى نص» وUTF-8 أو أيًّا من UTF-16، والصق التفريغ أو الست عشري المجرد، واضغط «تنزيل». والملف الذي يحفظه الزر، bytes.bin، يحمل البايتات المقروءة مما ألصقته بالضبط، نصًا كانت أم لا، فهو يؤدي عمل xxd -r؛ ثم أعد إليه اسمه الذي كان له.
هل من الآمن لصق ست عشري من قاعدة بيانات في بيئة الإنتاج أو من سجل؟
نعم، فيما يخص التحويل. فهو يجري على جهازك أنت، أيًّا كان اتجاهه: الست عشري الذي تلصقه، والنص الذي يصير إليه، وأي ملف يحفظه الزر «تنزيل»، لا يُرسَل أيٌّ منها إلى أي مكان أبدًا.

أدوات ذات صلة

  • محوّل النص إلى ثنائي

    يكتب الثنائي البايت ببتاته الثمانية، وهناك يُقرأ نمط UTF-8: الحرف é هنا C3 A9 وهناك ‎11000011 10101001، فالبايت الأول يبدأ بـ110 لأن الحرف يشغل بايتين، والثاني بـ10 لأنه يكمله. وهذه الصفحة تتيح الثنائي أيضًا، وتلك تُفتح عليه.

  • فاحص محارف يونيكود

    اعرف بالضبط من أي محارف يتألف النص.

  • محوّل أنظمة العد

    إذا كتبت 255 في هذه الصفحة حصلت على ثلاثة بايتات، واحد لكل محرف: ‎32 35 35. أما تلك الصفحة فتقرأ 255 عددًا وتحوّل القيمة نفسها، وهي في الست عشري ff.

  • Base64

    يرمّز ويفكّ ترميز Base64 — بدعم UTF-8 كامل.