ما هو Base64؟ شرح الترميز
Base64 طريقة لتمثيل البيانات الثنائية — الصور والملفات والبايتات المشفّرة وأي شيء آخر — باستخدام 64 حرفاً قابلاً للطباعة فقط (A–Z وa–z و0–9 و+ و/). وُجد لأن كثيراً من القنوات صُممت للنص: البريد الإلكتروني وJSON وXML وعناوين URL وترويسات HTTP وملفات تعريف الارتباط تستطيع جميعها نقل سلسلة Base64 بأمان حيث كانت البايتات الخام ستتلف أو تُرفض.
يشرح هذا الدليل كيف يعمل الترميز، ومتى يكون الخيار الصحيح، والفرق بين Base64 وBase64URL، والأخطاء التي تنتج مخرجات مشوّهة — بما فيها الخطأ الأهم: Base64 ليس تشفيراً.
كيف يعمل ترميز Base64
يأخذ Base64 المدخلات ثلاثة بايتات (24 بت) في كل مرة ويقسمها إلى أربع مجموعات من ستة بتات. تُربط كل قيمة من ستة بتات (0–63) بحرف واحد من الأبجدية. ثلاثة بايتات تدخل وأربعة أحرف تخرج — ولهذا يكون ناتج Base64 دائماً أكبر من المدخل بنحو 33%.
وعندما لا يكون طول المدخل من مضاعفات الثلاثة، تُحشى المجموعة الأخيرة ببتات صفرية ويُلحق حرف «=» أو حرفان حتى يعرف مفكّك الترميز عدد البايتات الحقيقية المتوقعة.
المثال أدناه خطوة خطوة: النص Hi! ثلاثة بايتات (Text ثم Bytes)، تُقسم بتاتها الأربعة والعشرون إلى أربع مجموعات من ستة بتات (Groups)، قيمها 18 و6 و36 و33 (Index)، وهي في الأبجدية الأحرف S وG وk وh، فالناتج SGkh. أما Hi فبايتان فقط: تُكمَّل المجموعة الأخيرة ببتّين صفريين ويُلحق حرف «=» واحد، فالناتج SGk=.
Hi! — ثلاثة بايتات، دون حشو
النص (Text)
H i !
البايتات (Bytes)
01001000 01101001 00100001
المجموعات (Groups)
010010 000110 100100 100001
القيم (Index)
18 6 36 33
الناتج (Base64)
S G k h
Hi — بايتان، وحرف «=» واحد للحشو
النص (Text)
H i
البايتات (Bytes)
01001000 01101001 00
المجموعات (Groups)
010010 000110 100100
القيم (Index)
18 6 36
الناتج (Base64)
S G k =
الخطوط المتصلة حدود البايتات، والمتقطعة حدود مجموعات الستة بتات. والخانات الباهتة ليست من المدخل: البتات الصفرية وحرف «=» المضافة حشواً، والمكان الفارغ للبايت الناقص.
النسخة النصية
Text: Hi!
Bytes: 01001000 01101001 00100001
Groups: 010010 000110 100100 100001
Index: 18 6 36 33
Base64: S G k h → "SGkh"
Text: Hi (2 bytes → one "=" of padding)
Base64: SGk=Base64 ليس تشفيراً
يستطيع أي شخص فك ترميز Base64 فوراً دون أي مفتاح — فهو ترميز قابل للعكس، مثل كتابة رقم بالنظام السداسي عشري. لا يخفي شيئاً. كلمة المرور أو مفتاح API أو الرمز «المحمي» بـ Base64 مكشوف لكل من يراه. استخدم تشفيراً حقيقياً (AES وTLS) لحماية البيانات، وBase64 لنقلها فقط.
متى تستخدم Base64
- تضمين الصور أو الخطوط الصغيرة في HTML أو CSS أو JSON كعناوين data: URI.
- إرسال محتوى ثنائي داخل حمولة JSON أو XML التي لا تحمل سوى النص.
- مصادقة HTTP Basic: تحمل الترويسة Base64 لـ «username:password» (للنقل فقط — وعبر HTTPS دائماً).
- رموز JWT وغيرها من الرموز التي تستخدم النسخة الآمنة لعناوين URL في ترويستها وحمولتها وتوقيعها.
- مرفقات البريد الإلكتروني (MIME) وأي بروتوكول قديم يتوقع نصاً بسبعة بتات.
- ليس للملفات الكبيرة عندما توجد قناة ثنائية — فالزيادة 33% وخطوة الترميز الإضافية هدر محض.
الفرق بين Base64 وBase64URL
يستخدم Base64 القياسي «+» و«/» ولكليهما معنى خاص في عناوين URL، وحشو «=» الذي غالباً ما يُرمَّز بالنسبة المئوية. أما Base64URL (RFC 4648 §5) فيستبدلهما بـ «-» و«_» ويحذف الحشو عادةً، فيمكن استخدام الناتج في عنوان URL أو اسم ملف أو رمز JWT دون تهريب إضافي. ومفكّك الترميز الذي يتوقع نسخة سيرفض الأخرى، وهذا أكثر أسباب فشل فك ترميز رمز «صالح» شيوعاً.
ترميز النصوص: انتبه إلى مجموعة الأحرف
يرمّز Base64 البايتات لا الأحرف، لذا يجب تحويل النص إلى بايتات أولاً — بـ UTF-8 في الغالبية الساحقة من الحالات. تصبح الأحرف العربية والهندية والرموز التعبيرية تسلسلات متعددة البايتات؛ وإذا استخدم المرمّز UTF-8 وافترض مفكّك الترميز Latin-1 (أو العكس) خرج النص مشوّهاً. عندما يختلف نظامان حول سلسلة Base64، فمجموعة الأحرف هي أول ما يجب فحصه.
لماذا يفشل فك الترميز
- أبجدية خاطئة — سلسلة Base64URL («-» و«_») تُمرَّر إلى مفكّك قياسي، أو العكس.
- حشو ناقص أو زائد — تحذف بعض المرمّزات «=»، بينما تشترط المفكّكات الصارمة طولاً من مضاعفات الأربعة.
- مسافات أو فواصل أسطر داخل السلسلة — يلفّ MIME الأسطر عند 76 حرفاً؛ أزلها قبل فك الترميز.
- ترميز مزدوج — سلسلة رُمّزت بـ Base64 مرتين تبدو صالحة لكنها تُفكّ إلى Base64 آخر.
- لم تكن Base64 أصلاً — قد يبدو Hex أو الهاش أو رمز عشوائي مشابهاً. يستخدم Base64 الأحرف الأربعة والستين بالضبط مع «=»، وطوله من مضاعفات الأربعة عند الحشو.
الأسئلة الشائعة
هل Base64 آمن؟
لا. إنه ترميز قابل للعكس دون مفتاح. لا يوفر أي سرّية على الإطلاق؛ استخدم التشفير لذلك.
لماذا ينتهي Base64 بـ «=» أو «==»؟
الحشو. تُعالج المدخلات في مجموعات من ثلاثة بايتات؛ وعندما يتبقى بايت أو بايتان يُلحق «==» أو «=» حتى يعرف مفكّك الترميز الطول الحقيقي.
كم يكبر ناتج Base64؟
بنحو 33% — كل 3 بايتات تصبح 4 أحرف. صورة بحجم 300 كيلوبايت تصبح نصاً بنحو 400 كيلوبايت.
هل يمكن لـ Base64 ترميز صورة أو ملف PDF؟
نعم — يعمل Base64 على أي بايتات. هكذا تضمّن عناوين data: URI الصور في HTML وهكذا تنتقل الملفات داخل واجهات JSON API.
ما الفرق بين Base64 وHex؟
كلاهما يمثّل البايتات كنص. يستخدم Hex 16 حرفاً ويضاعف الحجم (حرفان لكل بايت)؛ ويستخدم Base64 64 حرفاً ويزيد الحجم بالثلث. Hex أسهل في القراءة؛ وBase64 أكثر إيجازاً.
ما الفرق بين Base64 وترميز URL؟
ترميز URL (النسبة المئوية) يهرّب الأحرف غير الآمنة في عنوان URL فقط ويترك الأحرف العادية كما هي. أما Base64 فيعيد ترميز كل بايت. وكثيراً ما يُجمع بينهما: قد تحتاج سلسلة Base64 إلى ترميز بالنسبة المئوية قبل وضعها في معامل استعلام، ما لم تُستخدم النسخة الآمنة لعناوين URL.
المراجع
- RFC 4648: The Base16, Base32, and Base64 Data Encodingsأبجديات Base64 وBase64url وقواعد الحشو وترميز hex (Base16).
- Base64 — MDN Glossary — MDNBase64 في المتصفح: btoa/atob والنسخة الآمنة لعناوين URL وحجم الزيادة عند ترميز البيانات الثنائية.
- RFC 2397: The "data" URL schemeكيف تُضمَّن الملفات الصغيرة داخل عنوان URL بالصيغة data:<mediatype>;base64,<data>.
تمرين عملي
شخّص مشكلات Base64 في واجهة برمجية لرفع المستندات
أنت تختبر خدمة المستندات (Documents service) في منصة خدمات حكومية إلكترونية (مثال خيالي) قبل الإصدار 3.2. يرفق المتقدّمون المستندات الداعمة في تطبيقات الجوال، التي ترسل كل ملف داخل طلب JSON على شكل سلسلة Base64؛ ويستدعي نظامُ وكالة سفر شريكة الواجهةَ البرمجية نفسها مباشرةً بمصادقة HTTP Basic؛ ويحمل بريد الإيصال رابطاً فيه مرجع بترميز Base64. تعرض المادة أدناه المتطلب، ومقتطفاً من عقد الواجهة البرمجية (API contract)، وملاحظتين عن المنصة، وست ملاحظات جُمعت في بيئة Staging.
قرّر لكل ملاحظة هل تكشف عيباً، واشرحها بقاعدة Base64 التي تقف وراءها، وحدّد أين يجب أن يكون الإصلاح؛ ثم صمّم الاختبارات التي تلتقط هذه المشكلات في المرة القادمة. اعمل بالورقة والقلم، وبأداتَي ترميز Base64 وفك ترميزه (في أداة فك الترميز خيار Latin-1 ضمن «فك ترميز النص كـ»)، وأداة فك ترميز URL، وأداة لتحليل القيم الحدّية. خصّص 40–45 دقيقة؛ فحساب الحجم لا يحتاج إلا إلى الضرب والقسمة.
منصة خدمات حكومية إلكترونية (مثال خيالي) - خدمة المستندات، الإصدار 3.2
اختبار النظام في بيئة Staging
المتطلب DOC-4
يستطيع المتقدّم أن يرفق بطلبه ملف PDF أو JPG أو PNG حجمه حتى 5 ميغابايت
(5,000,000 بايت). ويُرفض الملف الأكبر برمز الحالة HTTP 413 والخطأ
FILE_TOO_LARGE («حجم الملف أكبر من 5 ميغابايت»).
عقد الواجهة البرمجية (مقتطف)
POST /api/v3/applications/{id}/documents Content-Type: application/json
content الملف بترميز Base64 (RFC 4648، الأبجدية القياسية، مع الحشو)
النجاح 201 مع معرّف المستند
الأخطاء 400 INVALID_BASE64، 413 FILE_TOO_LARGE
GET /api/v3/receipts?ref={ref} ref = 12 بايتاً عشوائياً بترميز Base64
المستدعون: تطبيقا iOS وAndroid (يفحصان حدّ 5 ميغابايت قبل الرفع)،
ونظام وكالة سفر شريكة (مصادقة HTTP Basic)
ملاحظتان عن المنصة
ترفض بوابة الواجهات البرمجية (API gateway) أي جسم طلب يزيد على 6,000,000 بايت
بصفحة HTML خاصة بها مع HTTP 413، قبل أن يصل الطلب إلى خدمة المستندات.
إعدادات السجلات في البوابة واحدة في بيئة Staging وفي الإنتاج.
عيّنة رفع (قيمة Base64 مختصرة)
{"fileName":"family-book.pdf","mimeType":"application/pdf","content":"JVBERi0xLjcK..."}
حجم هذا الجسم دون قيمة Base64 هو 72 بايتاً.
الملاحظات
O1 الملف family-book.pdf بحجم 4,800,000 بايت يجتاز فحص التطبيق: HTTP 413
وصفحة HTML من البوابة. الملف birth-certificate.pdf بحجم 4,200,000 بايت: HTTP 201.
O2 تطبيق Android: كل عملية رفع تفشل بالرمز 400 INVALID_BASE64، والملفات نفسها
تُرفع من iOS بنجاح. في طلب Android الملتقَط يحوي "content" الرمز \n
(فاصل سطر) بعد كل 76 حرفاً.
O3 رابطا إيصال من رسالتَي بريد إلكتروني:
GET /api/v3/receipts?ref=Lm0x8Qp/Vt2aKc3Q 200، نُزِّل الإيصال
GET /api/v3/receipts?ref=k7Qd2+fA9w1Z0LsE 400 "Invalid reference"
سجل الخدمة للطلب الثاني: ref = "k7Qd2 fA9w1Z0LsE"
O4 سجل الوصول في البوابة، استدعاء من الشريك:
POST /api/v3/applications 201 Authorization: Basic YWdlbmN5MDc6VmlzYSNUZXN0MjY=
تعليق المطوّر: «لا بأس بإبقائه، فالترويسة مرمَّزة ولا يستطيع أحد قراءتها».
O5 يرسل التطبيقان اسم صاحب المستند في ترويسة، بترميز Base64 لأن قيم الترويسات
يجب أن تبقى ASCII: X-Doc-Owner: 2LPYp9ix2Kk=
وتعرض شاشة المراجعة في النظام الداخلي (Back office) اسمه هكذا: سارة
O6 ملاحظة مختبِر على ثلاث عمليات رفع ناجحة: «يبدو content تالفاً، ففي آخره
علامات = زائدة، والأحجام لا تطابق الملفات».
الملف الحجم (بايت) طول content (حرف) ينتهي بـ
passport-photo.png 48,211 64,284 ==
salary-certificate.pdf 120,005 160,008 =
lease-contract.jpg 96,300 128,400 (بلا =)- فكّ ترميز كل قيمة Base64 في المادة، واكتب ما تحتويه كل منها.
- في O1 احسب طول Base64 وحجم جسم الطلب لأكبر ملف مسموح، ثم أكبر ملف تسمح البوابة بمروره. اذكر أي الملفات الصالحة تفشل، وما الذي يتوقعه DOC-4 بدلاً من ذلك.
- في الملاحظات من O2 إلى O6 قرّر: هل هي عيب أم لا، وما قاعدة Base64 التي تفسّرها، وأين يجب أن يكون الإصلاح (تطبيق Android، أو الشيفرة التي تبني الرابط، أو البوابة، أو النظام الداخلي، أو لا مكان).
- استخرج قيم اختبار حجم الملف بتحليل القيم الحدّية الثنائي (2-value BVA) لحدّ المتطلب ولحدّ البوابة معاً، أي اختبر كل قيمة حدّية وأقرب قيمة مجاورة لها في القسم المجاور: هنا أكبر حجم يُقبل والحجم الذي يزيد عليه ببايت واحد، ثم أضف أحجاماً تغطي كل حالة من حالات الحشو.
- اكتب الاختبارات السلبية لحقل
contentولمرجع الإيصال مع النتيجة المتوقعة لكل منها، والأسئلة التي سترسلها إلى مالك الواجهة البرمجية.
إظهار الإجابة النموذجية
القيم بعد فك الترميز. JVBERi0xLjcK تُفكّ إلى %PDF-1.7 يليها فاصل سطر، وهي الترويسة التي يبدأ بها ملف PDF، فـ content يحمل بايتات الملف فعلاً. وYWdlbmN5MDc6VmlzYSNUZXN0MjY= تُفكّ إلى agency07:Visa#Test26، أي اسم مستخدم الشريك وكلمة مروره. و2LPYp9ix2Kk= تُفكّ إلى الاسم العربي سارة عندما تُقرأ بايتاتها D8 B3 D8 A7 D8 B1 D8 A9 بترميز UTF-8، وإلى سارة بالضبط عندما تُقرأ البايتات نفسها بترميز Latin-1. أما مرجعا الإيصال فيُفكّ كل منهما إلى 12 بايتاً عشوائياً، ولا يُتوقع فيهما نص مقروء.
O1: عيب في إعدادات البوابة. يحوّل Base64 كل ثلاثة بايتات إلى أربعة أحرف، ويقرّب المجموعة الأخيرة إلى الأعلى. فأكبر ملف مسموح، 5,000,000 بايت، يساوي 1,666,667 مجموعةً، أي إن طول content 6,666,668 حرفاً (مع حرف حشو «=» واحد)، والجسم 6,666,668 + 72 = 6,666,740 بايتاً، وهذا فوق حدّ البوابة البالغ 6,000,000. وأكبر ملف يمرّ: يبقى لـ content 6,000,000 − 72 = 5,999,928 حرفاً، و5,999,928 ÷ 4 = 1,499,982 مجموعةً كاملة، و1,499,982 × 3 = 4,499,946 بايتاً. لذلك، مع 72 بايتاً من JSON كما في العيّنة، يُرفض كل ملف صالح حجمه من 4,499,947 إلى 5,000,000 بايت (فالملف family-book.pdf بحجم 4,800,000 بايت يحتاج جسماً من 6,400,072 بايتاً، بينما يُرمَّز birth-certificate.pdf بحجم 4,200,000 بايت إلى 5,600,000 حرف فيمرّ)، ويتلقى المتقدّم صفحة HTML من البوابة بدلاً من خطأ مفهوم. والملفات التي تتجاوز الحد تتلقى استجابة خاطئة أيضاً: فملف من 5,000,001 بايت يرسله نظام الشريك، الذي لا يسبقه فحص التطبيق، لا يصل إلى الخدمة أصلاً، فلا يعود الخطأ FILE_TOO_LARGE الذي يشترطه DOC-4 أبداً.
وبمصطلحات ISTQB فإن الإخفاق (Failure) هو الاستجابة 413 لملف صالح، والعيب هو حدّ لجسم الطلب ضُبط على حجم الملف الخام لا على الطلب المرمَّز. أبلغ عنه على إعدادات البوابة، مع DOC-4 أساساً للاختبار (Test basis). أما طريقة الإصلاح فقرار الفريق: رفع الحد فوق أكبر جسم مرمَّز مع هامش لأسماء الملفات الطويلة، أو رفع الملفات بصيغة ثنائية (مثل multipart/form-data) بدلاً من Base64 داخل JSON، وهذا يلغي أيضاً زيادة الثلث. وأضف ملاحظة للمطورين: الملفان بحجم 5,000,000 و5,000,001 بايت يُرمَّزان كلاهما إلى 6,666,668 حرفاً، لذا يجب فحص قاعدة الحجم على البايتات بعد فك الترميز، لا على طول سلسلة Base64 أبداً.
O2: عيب في تطبيق Android. فاصل السطر بعد كل 76 حرفاً هو التفاف الأسطر على طريقة MIME. ينص RFC 4648 §3.1 على أن المرمِّزات يجب ألا تضيف فواصل أسطر ما لم تطلب ذلك المواصفة التي تستخدم Base64، والعقد لا يطلبه؛ وينص §3.3 على أن مفكّك الترميز يجب أن يرفض الأحرف الخارجة عن الأبجدية ما لم تنص المواصفة على غير ذلك. فاستجابة الخدمة 400 INVALID_BASE64 صحيحة، ونجاح iOS يثبت أن الملفات نفسها سليمة. ويمكنك أن ترى نوعَي مفكّك الترميز جنباً إلى جنب: رمّز ملفاً صغيراً بأداة ترميز Base64 مع ضبط «التفاف السطر» على «76 حرفاً (MIME)»، ثم الصق الناتج في أداة فك ترميز Base64، وهي متسامحة: تتجاهل فواصل الأسطر وتذكر عدد المسافات البيضاء التي تجاهلتها. أما خدمة المستندات فصارمة، كما يطلب الـ RFC افتراضياً. الإصلاح: أن يُخرج مرمِّز Android القيمة في سطر واحد. واطلب من مالك الواجهة البرمجية أن يكتب في العقد صراحةً: «سطر واحد بلا مسافات بيضاء».
O3: عيب في طريقة بناء رابط الإيصال. المرجع الثاني يحوي «+». فالرابط يضع Base64 القياسي في سلسلة الاستعلام (Query string) دون ترميز بالنسبة المئوية، والخدمة تقرأ سلسلة الاستعلام بقواعد ترميز النماذج (Form encoding) التي يعني فيها «+» مسافة، فتستلم k7Qd2 fA9w1Z0LsE وترفضه. وأداة فك ترميز URL تعيد إنتاج ذلك: مع تفعيل «فك ترميز + كمسافة» يخرج k7Qd2+fA9w1Z0LsE بصورة k7Qd2 fA9w1Z0LsE. والمرجع الأول ينجح فقط لأنه لا يحوي «+»؛ أما «/» فيه فمسموح في سلسلة الاستعلام، لكنه سيكسر المسار لو نُقل المرجع يوماً إلى المسار نفسه. ولأن المراجع بايتات عشوائية، يبدو فشل الروابط عشوائياً أيضاً، ولهذا كثيراً ما يُبلَّغ عن هذا النوع من العيوب على أنه متقطع. الإصلاح: استخدام Base64URL (RFC 4648 §5) للمرجع، فلا تحتاج القيمتان k7Qd2-fA9w1Z0LsE وLm0x8Qp_Vt2aKc3Q إلى أي تهريب؛ أو ترميز القيمة بالنسبة المئوية فيصبح «+» هو %2B (تُظهره أداة ترميز URL)، لكن نسيان ذلك أسهل. ويجب أن تبقى الروابط المرسلة سابقاً بالبريد صالحة بعد الإصلاح: اسأل كيف ستُقبل المراجع القديمة.
O4: عيب أمني، وهو أخطر الملاحظات الست لأنه يكشف بيانات اعتماد. تُفكّ الترويسة في ثوانٍ إلى agency07:Visa#Test26، أي إن سجل البوابة يحفظ كلمة مرور الشريك بصيغة مقروءة لكل من يستطيع قراءة السجلات، والإنتاج يسجّل بالطريقة نفسها. وتعليق المطوّر خاطئ: Base64 ترميز بلا مفتاح وليس تشفيراً، وHTTPS يحمي بيانات اعتماد Basic أثناء النقل فقط، لا بعد كتابتها في سجل. أبلغ عنه بخطورة عالية، واذكر في التقرير اسم المستخدم مع إخفاء كلمة المرور. الإصلاح المتوقع: إخفاء ترويسة Authorization أو حذفها من سجل البوابة ومن أي سجل أو أداة مراقبة أخرى تسجّل الترويسات، وتغيير بيانات الاعتماد المكشوفة. اختبار التأكيد: كرّر استدعاء الشريك وتحقق من أن السجل لا يُظهر أي بيانات اعتماد؛ وفي اختبارات الانحدار افحص الترويسات الأخرى التي تحمل أسراراً، مثل مفاتيح API ورموز Bearer.
O5: عيب في النظام الداخلي. التطبيقان على صواب: 2LPYp9ix2Kk= هو ترميز UTF-8 للاسم سارة (أربعة أحرف في ثمانية بايتات). أما النظام الداخلي فيحوّل البايتات بعد فك الترميز إلى نص بترميز Latin-1، حرفاً لكل بايت، فيصبح D8 هو Ø وB3 هو ³، والنتيجة سارة؛ ويعيد إنتاجها بالضبط اختيارُ «Latin-1 / سلسلة ثنائية» في «فك ترميز النص كـ» بأداة فك ترميز Base64. وتتابُع Ø أو Ù، يلي كلاً منهما رمز آخر، علامة نموذجية على نص عربي بترميز UTF-8 قُرئ بترميز Latin-1. الإصلاح: قراءة البايتات بعد فك الترميز بترميز UTF-8. بيانات الاختبار لاختبار التأكيد ولحزمة الانحدار: اسم عربي، واسم هندي بالخط الديوناغري (ثلاثة بايتات لكل حرف في UTF-8)، واسم لاتيني فيه حرف بعلامة تشكيل مثل José (الحرف é بايتان)، واسم فيه رمز تعبيري إن كان الحقل يسمح به (أربعة بايتات)، واسم بأحرف ASCII فقط يجب أن يبقى كما هو.
O6: ليس عيباً. الحشو يتبع حجم الملف لأن Base64 يعمل على مجموعات من ثلاثة بايتات: 48,211 يترك باقياً قدره 1 عند القسمة على 3 فتنتهي القيمة بـ «==»، و120,005 يترك 2 فتنتهي بـ «=»، و96,300 يترك 0 فلا حشو. (طريقة سريعة للتحقق: باقي قسمة العدد على 3 يساوي باقي قسمة مجموع أرقامه على 3.) والأطوال تساوي 4 × (الحجم ÷ 3 مقرَّباً إلى الأعلى): 16,071 × 4 = 64,284 و40,002 × 4 = 160,008 و32,100 × 4 = 128,400، أي أكثر من كل ملف بنحو الثلث كما هو متوقع. أغلق الملاحظة بأنها ليست عيباً مع هذا الحساب، واحتفظ بالملفات الثلاثة: فهي معاً تغطي حالات الحشو كلها.
قيم اختبار حجم الملف (تحليل القيم الحدّية الثنائي). حدّ المتطلب: 5,000,000 بايت تُقبل بالرمز 201، و5,000,001 بايت تُرفض بالرمز 413 والخطأ FILE_TOO_LARGE؛ أرسل الحالتين إلى الواجهة البرمجية مباشرةً كما يفعل نظام الشريك، لا عبر التطبيق فقط. حدّ البوابة لاسم الملف في العيّنة، وهو حدّ تقني لا يذكره المتطلب: 4,499,946 بايتاً (الجسم 6,000,000 بالضبط، يُقبل) و4,499,947 بايتاً (الجسم 6,000,004، ترفضه البوابة اليوم، ويُقبل بعد إصلاح العيب). حالات الحشو: ثلاثة أحجام بواقي قسمتها على 3 هي 0 و1 و2، مثل ملفات O6. وشغّل حدّ البوابة أيضاً بأطول اسم ملف مسموح، لأن كل بايت إضافي في JSON يخفض أكبر ملف يمرّ، واسأل ماذا يتوقع DOC-4 لملف فارغ. وأبقِ الحالتين 4,499,947 و5,000,000 في حزمة الانحدار بعد الإصلاح.
اختبارات سلبية لـ content، يُتوقع في كل منها 400 INVALID_BASE64 وعدم تخزين أي شيء، بحسب نص العقد اليوم: فواصل أسطر أو مسافات داخل القيمة؛ وحرفا Base64URL «-» أو «_»؛ وحرف خارج الأبجدية مثل «*»؛ وطول ليس من مضاعفات الأربعة (بحذف الحشو)؛ وعلامة «=» في وسط القيمة. أما الملف المرمَّز مرتين فهو Base64 صالح تُفكّ بايتاته إلى نص Base64 (يبدأ بـ SlZCRVJp بدلاً من JVBERi0): ينبغي رفضه لأنه ليس PDF إن كانت الخدمة تفحص محتوى الملف مقابل mimeType، فاسأل هل تفعل. ولمرجع الإيصال: مراجع تحوي «+» و«/»، و«=» إن كان طول المراجع قد يتغير؛ ومرجع فيه مسافة؛ ومرجع مرمَّز بالنسبة المئوية (%2B)؛ ومرجع سليم الصيغة لكنه غير موجود، ويجب أن يعيد خطأً من جهة العميل (Client error)، لا 500 أبداً (ولا يحدد المقتطف أيّ خطأ، فاسأل عنه).
أسئلة لمالك الواجهة البرمجية: هل تقبل الخدمة غياب الحشو والمسافات البيضاء أم ترفضهما، وهل يمكن أن ينص العقد على ذلك صراحةً؟ ما أطول اسم ملف مسموح، بما أنه يحرّك حدّ البوابة؟ هل تتحقق الخدمة من أن البايتات بعد فك الترميز تطابق mimeType؟ هل ستنتقل مراجع الإيصالات إلى Base64URL، وكيف ستبقى الروابط المرسلة سابقاً صالحة؟ وهل Base64 داخل JSON هو القناة المناسبة أصلاً لملفات حتى 5 ميغابايت، مع زيادة الثلث التي يضيفها؟
إن اختلفت أرقامك فتحقق من أنك قرّبت عدد المجموعات إلى الأعلى عند حساب الطول المرمَّز وإلى الأدنى عند حساب أكبر ملف يمرّ، ومن أنك أضفت 72 بايتاً من JSON.
تقدّمك في هذا الموضوع
سجّل الدخول لتتابع تقدّمك
علّم الموضوعات مكتملة، وتابع من حيث توقفت، وافتح امتحانات التخصص.
جزء من مسار تعلم ضمان الجودة
قبل هذا الموضوع
الموضوعات التالية
الأدوات المذكورة في هذا الدليل
ترميز النصوص أو الملفات إلى Base64 (القياسي أو الآمن لعناوين URL) داخل متصفحك.
فكّ ترميز سلاسل Base64 أو Base64url إلى نص، مع إصلاح الحشو تلقائياً.
ترميز النص بالنسبة المئوية (percent-encoding) لاستخدامه بأمان في عناوين URL وسلاسل الاستعلام وبيانات النماذج.
تحويل النص إلى بايتات سداسية عشرية (UTF-8) مع فواصل مخصصة وحالة أحرف قابلة للتحديد.
تحويل النص إلى ثنائي (بتات) وإعادة الثنائي إلى نص.
فكّ ترميز ترويسة JWT وحمولته، وفحص المطالبات (claims) والتحقق من انتهاء الصلاحية — بالكامل داخل متصفحك.