هناك مشكلتان قديمتان في نقل البيانات عبر الإنترنت: الأولى أن بعض القنوات (البريد الإلكتروني، JSON، HTML) صُممت للنص لا للبيانات الثنائية كالصور، والثانية أن الروابط (URLs) تقبل مجموعة محدودة من الحروف. Base64 يحل الأولى، وترميز النسبة المئوية (Percent-encoding) يحل الثانية. كلاهما ترميز قابل للعكس، وليس أي منهما تشفيرًا.
Base64: البيانات الثنائية كنص
كيف يعمل؟
- يأخذ البيانات كسلسلة بتات.
- يقسمها إلى مجموعات من 6 بتات.
- يحول كل مجموعة (0–63) إلى حرف من أبجدية من 64 حرفًا:
A–Zوa–zو0–9و+و/. - إذا لم يكن الطول من مضاعفات 3 بايتات، يضيف
=أو==للحشو.
مثال
النص: Man
البايتات: 01001101 01100001 01101110
6 بتات: 010011 010110 000101 101110
القيم: 19 22 5 46
Base64: T W F u → TWFu
النص العربي في Base64
يُحوَّل النص أولًا إلى بايتات UTF-8 (كل حرف عربي غالبًا بايتان)، ثم يُرمَّز:
مرحبا → 2YXYsdit2KjYpw==
في JavaScript، الدالة btoa() لا تقبل الحروف غير اللاتينية مباشرة. الطريقة الصحيحة:
const enc = btoa(String.fromCharCode(...new TextEncoder().encode('مرحبا')));
const dec = new TextDecoder().decode(Uint8Array.from(atob(enc), c => c.charCodeAt(0)));
الحجم
كل 3 بايتات تصبح 4 حروف، أي زيادة نحو 33%. لهذا تكبر مرفقات البريد عند الإرسال؛ التفاصيل في دليل ضغط ملفات PDF.
أين يُستخدم Base64؟
- مرفقات البريد الإلكتروني (MIME).
- روابط data URL لتضمين صور صغيرة في HTML أو CSS.
- JSON وواجهات البرمجة لنقل ملفات صغيرة داخل نص.
- رموز JWT للمصادقة (بصيغة Base64URL).
- ترويسة Basic Authentication في HTTP.
أداة Base64 ترمّز النصوص والملفات وتفك ترميزها داخل متصفحك.
Base64URL
نسخة معدلة للاستخدام داخل الروابط: تستبدل + بـ - و/ بـ _، وغالبًا تحذف =. تُستخدم في JWT وبعض المعرفات.
روابط data URL
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..." alt="شعار">
مفيدة لأيقونات صغيرة جدًا (أقل من 1–2 كيلوبايت) لتوفير طلب HTTP. ضارة للصور الكبيرة: تزيد الحجم 33%، ولا تُخزَّن مؤقتًا بشكل منفصل، وتضخم ملف HTML أو CSS. للصور العادية استخدم ملفات منفصلة بصيغ حديثة كما في دليل تحسين الصور.
ترميز الروابط (Percent-encoding)
لماذا نحتاجه؟
الروابط تسمح فقط بحروف ASCII محددة. الحروف الأخرى (العربية، المسافات، بعض الرموز) يجب ترميزها. كذلك الرموز التي لها معنى بنيوي في الرابط (? و& و= و/ و#) تحتاج ترميزًا إذا وردت داخل قيمة.
كيف يعمل؟
- يُحوَّل الحرف إلى بايتات UTF-8.
- يُكتب كل بايت بصيغة
%متبوعة برقمين ست عشريين.
| الحرف | UTF-8 | الترميز |
|---|---|---|
| مسافة | 20 | %20 (أو + في النماذج) |
| & | 26 | %26 |
| ا | D8 A7 | %D8%A7 |
| م | D9 85 | %D9%85 |
| € | E2 82 AC | %E2%82%AC |
مثال: بحث بالعربية
https://example.com/search?q=مطاعم الرياض
↓
https://example.com/search?q=%D9%85%D8%B7%D8%A7%D8%B9%D9%85%20%D8%A7%D9%84%D8%B1%D9%8A%D8%A7%D8%B6
المتصفحات تعرض الرابط العربي مقروءًا في شريط العنوان، لكنها ترسله مرمّزًا. وعند نسخه ولصقه في بعض التطبيقات يظهر بالشكل المرمّز الطويل.
في JavaScript
encodeURIComponent('مطاعم & مقاهي'); // '%D9%85...%20%26%20%D9%85...'
encodeURI('https://a.com/بحث?q=1'); // يرمّز العربية ويترك : / ? =
decodeURIComponent('%D8%A7'); // 'ا'
القاعدة: استخدم encodeURIComponent لكل قيمة معامل على حدة، لا للرابط كاملًا.
أداة ترميز الروابط ترمّز وتفك الترميز بالطريقتين.
الروابط العربية وتحسين محركات البحث
جوجل يفهم الروابط العربية، لكن مشاركتها تنتج روابط طويلة مرمّزة قد تبدو مريبة للمستخدم. لذلك تفضل كثير من المواقع العربية روابط لاتينية قصيرة (slug)، أو تقبل الطول من أجل وضوح الكلمة المفتاحية. اختر أسلوبًا واحدًا وثبّت عليه، واستخدم تحويلات 301 عند التغيير؛ راجع دليل التحويلات 301 و302.
مثال عملي: فك رمز JWT
رمز JWT المستخدم في تسجيل الدخول يتكون من ثلاثة أجزاء بصيغة Base64URL تفصلها نقاط: الترويسة، والحمولة، والتوقيع.
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMiLCJuYW1lIjoiU2FyYSJ9.<signature>
فك الجزء الأول يعطي {"alg":"HS256"}، والثاني {"sub":"123","name":"Sara"}. هذا يوضح نقطتين:
- أي شخص يحمل الرمز يستطيع قراءة محتواه، فلا تضع فيه بيانات سرية.
- الحماية في التوقيع لا في الترميز: الخادم يتحقق من التوقيع ليعرف أن الحمولة لم تُعدَّل.
من سطر الأوامر
# ترميز وفك ترميز نص
echo -n 'مرحبا' | base64 # 2YXYsdit2KjYpw==
echo '2YXYsdit2KjYpw==' | base64 --decode
# ترميز ملف كامل (مثلًا لتضمينه في JSON)
base64 -i logo.png -o logo.txt # macOS
base64 -w 0 logo.png > logo.txt # Linux دون فواصل أسطر
لاحظ -n مع echo: من دونها يُضاف سطر جديد إلى النص فيتغير الناتج، وهو سبب شائع لاختلاف النتائج بين الأدوات.
ترميزات أخرى قد تصادفها
- Hex (ست عشري): كل بايت بحرفين (0–9 وa–f)، يضاعف الحجم، ويُستخدم لعرض قيم التجزئة مثل SHA-256.
- Punycode: لأسماء النطاقات العربية، فيصبح النطاق العربي سلسلة تبدأ بـ
xn--في نظام DNS. - ترميز HTML: مثل
&و<لعرض الرموز الخاصة داخل الصفحة دون أن تُفسَّر كوسوم.
Base64 مقابل ترميز الروابط
| Base64 | Percent-encoding | |
|---|---|---|
| الغرض | بيانات ثنائية كنص | حروف غير مسموحة في الرابط |
| الزيادة في الحجم | نحو 33% ثابتة | 3 حروف لكل بايت مرمّز |
| يُستخدم في | البريد، data URL، JWT، APIs | الروابط، النماذج |
| قابل للقراءة | لا | جزئيًا |
هل أستخدم Base64 لتخزين الصور في قاعدة البيانات؟
غالبًا لا. تخزين الصور كنص Base64 يزيد حجمها الثلث، ويبطئ الاستعلامات، ويمنع التخزين المؤقت في المتصفح وشبكات CDN. الأفضل تخزين الملف في نظام ملفات أو خدمة تخزين سحابي، وحفظ رابطه فقط في قاعدة البيانات. يبقى Base64 مناسبًا لملفات صغيرة جدًا تُرسل مرة واحدة داخل طلب API، مثل توقيع أو صورة مصغرة.
أخطاء شائعة
- اعتبار Base64 تشفيرًا: أي شخص يفكه في ثانية. لحماية البيانات استخدم تشفيرًا حقيقيًا (AES، TLS)، ولكلمات المرور استخدم التجزئة؛ راجع دليل كلمات المرور القوية.
- الترميز المزدوج: ترميز قيمة مرمّزة أصلًا يحول
%20إلى%2520. - استخدام
btoaمع العربية مباشرة: يرمي خطأ “Invalid character”. - ترميز الرابط كاملًا بـ
encodeURIComponent: يحطمhttps://إلىhttps%3A%2F%2F. - الخلط بين
+والمسافة: في النماذج+تعني مسافة، وفي مسار الرابط تبقى+. - تضمين صور كبيرة كـ data URL في البريد أو الصفحة.