بسم الله الرحمن الرحيم
والصلاة والسلام على المبعوث رحمة للعالمين ... سيدنا محمد صلى الله عليه وسلم.. الصادق الوعد الأمين ..
تحية طيبة وبعد ...
أضع بين يديكم اليوم خوارزمية تشفير قمت بتصميمها منذ شهر تقريبا... لا أدري إن كان لها مماثل في فضاء العلم الواسع.أم لا.. والحمد لله على ما أنعم .. وله الفضل فيما أعطى...
أملا في أن تكون بذرة أسلوب جديد في التشفير ... لا أدعي أنها الأفضل ولكن رأيت أن أشاركها مع أهل الخبرة ...فبقاء العلم مكتوماً لن يفيد أحداً ...
إذا كنت تفضل قراءة الملف بشكل word ...
نبدأ باسم الله ...
تحية طيبة وبعد ..
1. تعتمد الخوارزمية في جوهرها على ترميز الحرف المستهدف بواحد وجميع الأحرف الباقية بصفر ..
(استخدمت كلمة استهداف لأنها الأنسب في هذا المجال إضافة إلى أسباب تتعلق ببلد المنشأ)
الكلمة التي سأعتمدها مثالا هنا هي happiness
باستهداف الحرف h ستكون العبارة المشفرة 100000000 ... (العبارة السابقة نعتبرها شيفرة جزئية تخص المحرفh)
باستهداف الحرف a ستكون العبارة المشفرة 010000000
باستهداف الحرف p ستكون العبارة المشفرة 001100000
باستهداف الحرف i ستكون العبارة المشفرة 000010000
باستهداف الحرف n ستكون العبارة المشفرة 000001000
باستهداف الحرف e ستكون العبارة المشفرة000000100
باستهداف الحرف s ستكون العبارة المشفرة000000011
ثم نصل الشيفرات الجزئية فتنتج الشيفرة الكلية ثم نحولها إلى الترميز الموجود عندنا وليكن ترميز ASCII مثلا...
2. طول الشيفرة
سيكون طول الشيفرة في هذه الحالة بالبايت .. هو
طول العبارة المشفرة * عدد المحارف المستخدمة \8 ..
في مثالنا طول العبارة happiness هو 9 وعدد المحارف المستخدمة 7 فطول الشيفرة 63 نضيف صفراً زائدا لكي تقبل القسمة على 8 ... فيكون طول الشيفرة : 8 بايت ...
وبفرض اعتمدنا ترميز ASCII فإن الشيفرة هي طول العبارة *32 وذلك في حال وجود جميع المحارف في الملف
رياضياً نكتب :
سيكون ذلك كبيرا جداً مقارنة بالأصل ...
3. من هنا جاءت الفكرة رقم 1 ..
بعد استهداف حرف معين.... نزيله من العبارة الأصلية ..فتنتج عبارة أقل حجماً من الأولى بعدد تكرار المحرف المحذوف ..
فمن سيحتاج إلى صفر يشير إلى وجود حرف تمت الإشارة إليه من قبل ....
مثال :
نتابع مع happiness
الحرف المستهدف h: 100000000
نحذف h من الكلمة فتصبح appiness
نستهدف aوتشفيره 10000000 أقصر بواحد من الطول
نحدف a فتصبح ppiness
نستهدف p وتشفيره 1100000أقصر ب 2
وهكذا ... سيكون تشفير آخر حرف هو عدد مرات تكراره فقط...
فالجزء المستعمل لتشفير ss سيكون 11 فقط ...
وبذلك يمكننا كتابة العلاقة المعبرة عن طول الشيفرة كما يلي :
حيث a هو عدد المحارف المستخدمة في نمط الترميز ( في نظام ASCII سيكون 256)
L هو طول المصدر ..(العبارة المطلوب تشفيرها )
Bjهو عدد تكرار المحرف ذو الدليل j
لاحظ أنه كلما قمنا بتشفير محرف ..سينقص طول الشيفرة الجزئية للمحرف التالي ...
ولكن هناك سلبية أخرى ... ففي كل الحروف السابقة ..
قمنا بترميز ss ب00 في آخر الشيفرات الجزئية ... ثم رمزناها ب11 في النهاية ..
أي أننا كتبنا 12صفراً دون جدوى ...
4. من هنا جاءت الفكرة رقم 2 ..
عملية الاستهداف يجب أن تكون مرتبة ...بحيث نقلل من الأصفار ما أمكن ..
فلو قمنا بتشفير ss من البداية سنوفّر 12 بت .. من الشيفرة الكلية ..
إحدى طرق الترتيب .. تكون .بحيث نستهدف العنصر المتكرر قبل أن نستهدف العنصر الغير متكرر ...
(وأؤكد على كلمة إحدى ... فالترتيب بهذا الشكل قد يكون سيئاً في بعض الحالات أو قليل الجدوى )
وبذلك سيصبح طول الشيفرة تابعاً لتكرار المعلومات ...
مثال :
Happiness:
سنرتب الحروف كما يلي : p,s,h,a,i,n,e
سيصبح التشفير وفق الترتيب السابق :
0011000000 p
0000011 s
10000 h
1000 a
100 i
10 n
1 e
أي أن الشيفرة الكلية أصبح طولها : 32 بت .. أي 4بايت ..
وسيكون طول الشيفرة كما في العبارة السابقة :
إلا أن التغيير أصبح في ترتيب العناصر ضمن المصفوفة B مصفوفة التكرارات ...
لاحظوا أن معظم الشيفرات الجزئية تحوي أصفاراً في نهايتها ...
ما الذي تخبرنا به هذه الأصفار ؟؟؟ عدد الحروف الباقية بعد انتهاء تكرارات المحرف المستهدف ...
هل يهمنا ذلك بالفعل ؟؟
5. من هنا جاءت الفكرة رقم 3
لنفرض أن المحرف المستهدف X
وعدد مرات تكراره Y
وطول المصدر هو Z .. المصدر ككل ..
فيكفيك أن تعرف :أماكن وجود X حتى وصولك إلى آخر مكان تواجد فيه X أي عندما يبلغ تكراره Y مرة
لأن الباقي سيكون أصفاراً في طبيعة الحال ...
أي أنه يمكننا اختصار المعلومة 001100000 إلى 0011
لأننا نعرف أن الباقي سيكون أصفاراً طالما أن Y,Zمعلومة
مثال :abcbbac
نرتب الاستهداف كما يلي : b,a,c
من أجل b تشفيرها 0101100 بحذف الأصفار على اليمين 01011 ثم نحذف b من الأصل فيصبح : acac
من أجل a تشفيرها 1010 بحذف الأصفار على اليمين 101 قم نحذف a من الأصل فيصبح cc
من أجل c تشفيرها 11
بالوصل تكون الشيفرة : 0101110111 طولها 10 وبإضافة 6 بت زائدة .. يكون لدينا 2 بايت حجم الشيفرة
لاحظ أن العبارة الأصل(الهدف) لا نستخدمها إلا مع المحرف الأول في الترتيب ..
وعند الانتقال إلى المحرف الثاني .. سيكون لدينا عبارة هدف جديدة ... خالية من المحرف السابق ..
يتطلب إيجاد طول الشيفرة الكلية حسابات طويلة بعض الشيء .. ولكن يمكننا اعتماد طول الشيفرة السابق كحد أقصى لا يمكن أن تتجاوزه الشيفرة الناتجة ..
هل انتهينا ؟؟؟
ماذا سنفهم من 0101110111 بدون معرفة الحروف المستعملة وعدد تكرارها؟؟؟لا شيء..
6. The Header
ليس خافياً أن رأس الملف له من الأهمية بقدر محتوى الملف ...
فدليل تفسير المحتوى غالبا يكون في البداية ......مثل PE في ملفات exe والرأس في BMP ..
غالباً لن يكون أي مفسر قادراً على ترجمة الشيفرة بدون Header ...
وأحياناً يكون الـHeader مخزناً ضمن المترجم ...
مثال بسيط : الإنسان عندما يترجم بين عدة لغات ... يحتفظ بـ Header يُشبه القاموس في رأسه بحيث يُفسّر كل كلمة من اللغة المجهولة (الشيفرة ) إلى لغته المعلومة (الأصل)
وببساطة يجب أن نفكر دوماً بأنه لا معنى للتشفير بدون فك التشفير .. ولذلك .. لا يوجد شيفرة يستحيل فكها ..لأنها ستحتوي معلومات لا أحد يفهمها ... وبالتالي لا نطلق عليها معلومات ..
نتابع ..
ما هي المعلومات التي نحتاجها للتفسير..(فك التشفير)
عدد المحارف المستخدمة ...في أغلب الملفات ستكون جميع المحارف مستخدمة من المحرف الصفري إلى المحرف رقم 255
المحارف المستخدمة ...بحيث تكون مرتبة كما ذكرنا سابقاً ...
عدد مرات التكرار لكل محرف ... ويكون بنفس ترتيب المحارف المذكور سابقاً ..
طول الشيفرة وطول النص المشفر..(أي طول الأصل ) ...ولكن طول الأصل يُعطى بمجموع تكرارات العناصر فلا داعي لكتابته ثانية ...
وربما إذا أردنا تطوير الخوارزمية أو أن نجعل لها عدة أساليب للتعامل مع الملفات ..
فسنحتاج إلى خانة تمثل الModeالذي نستعمله ...
وقد نحتاج إلى خانة تمثل عدد المرات التي تم تشفير الأصل بها ..فقد نشفر الشيفرة الناتجة عن تشفير الأصل ..وهنا سنعتبر الشيفرة الناتجة من المستوى الثاني ... ربما في حالات خاصة يمكننا الوصول إلى تشفير من المستوى العاشر ...وذلك في حال كون الملف قابلاً للضغط بهذه الخوارزمية ..
مثال ..نهائي..
الأصل(الهدف) : Ahmad
طول الهدف 5
عدد الأحرف 4
ترتيب الأحرف a,h,m,d
التكرار 2.1.1.1
الشيفرة 1001 1 1 1 1
الشيفرة مع الرأس : 54ahmd211110011111
طبعا نكتب الأرقام بحيث يحجز كل رقم 4بايت ... ( كلام واضح بالنسبة لمت تعامل مع الملفات من قبل وطرف التخزين والاسترجاع)
قبل الختام .. ورغم أن خوارزمية التشفير أصبحت واضحة ..لا مفر من بعض الحديث عن فك التشفير ..
والذي يُفترض أن يكون العملية المعاكسة تماماً للتشفير ...
إذاً .... لنُعد ترتيب خطوات التشفير بهدوء ..
1. يجب أن نعرف عدد المحارف المستخدمة وتعداد كل عنصر ...
2. نكتب في الرأس عدد العناصر المستخدمة
3. نكتب في الرأس المحارف المستخدمة بالترتيب الأفضل
4. نكتب تكرارات المحارف المستخدمة بنفس ترتيب المحارف في الخطوة السابقة
5. ننشئ مصفوفة خالية لنخزن فيها الشيفرة ..ونخزن العبارة الهدف في مصفوفة A ونمر على العناصر ..كما يلي:
a. طالما أن عدد المرات التي صادفنا فيها المحرف المستهدف أقل من عدد مرات تكراره ..نفذ ما يلي:
i. إذا كان العنصر الذي تمر عليه هو المحرف المستهدف خزّن في الشيفرة الرقم 1 وقم بزيادة المتحول الذي يخزن عدد المرات التي صادفنا فيها هذا المحرف
ii. إذا كان العنصر الذي تمر عليه مغاير للعنصر المستهدف خزن في الشيفرة الرقم 0 وقم بتخزين هذا المحرف في المصفوفة الجديدة ...
b. عند الخروج سيتبقى محارف في النهاية لا تحوي العنصر المستهدف ..انسخها إلى المصفوفة الجديدة
c. اعتبر المصفوفة الجديدة هي المصفوفة المستهدفة واذهب إلى الخطوة a إذا كانت المصفوفة الجديدة غير معدومة العناصر
6. اطبع الشيفرة بشكلها الثنائي بدمج كل 8 عناصر في عنصر واحد وانه الخوارزمية ...
والآن سنقوم بإعادة الخطوات من البداية بالنسبة لخوارزمية فك التشفير ... ولكن سنعكس العمليات ..
1. يجب أن نعرف عدد المحارف المستخدمة وتعداد كل عنصر ...
2. نأخذ من الرأس عدد العناصر المستخدمة
3. نأخذ من الرأس المحارف المستخدمة وعددها هو الرقم الذي أخذناه في الخطوة 1
4. نأخذ عدد تكرارات المحارف المستخدمة بنفس ترتيب المحارف في الخطوة السابقة وعددها نفس ما سبق
5. نخزن الشيفرة الهدف ..وننشئ مصفوفة فارغة Bحجمها هو مجموع تكرارات المحارف المأخوذة في الخطوة 4 ..سنخزن فيها العبارة الأصلية ..التي نريد إيجادها ..
6. نخزن الشيفرة في مصفوفة A ونمر على العناصر ..كما يلي:
a. طالما أن عدد المرات التي صادفنا فيها الرقم واحد أقل من عدد تكرار المحرف المستهدف..نفذ ما يلي:
i. إذا كان الموضع الحالي في Bيحتوي على عنصر من قبل قم بزيادة المتحول الذي يشير إلى موضعنا ضمن B وتجاوز هذه الدورة ..
ii. إذا كان الموضع الحالي في B لا يحتوي على عنصر بعد نفذ ما يلي :
1. إذا كان العنصر الذي تمر عليه هو الرقم واحد خزّن في A المحرف المستهدف وقم بزيادة المتحول الذي يخزن عدد المرات التي صادفنا فيها هذا المحرف وقم بزيادة المتحول الذي يشير إلى موضعنا ضمن B
2. إذا كان العنصر الذي تمر عليه هو الرقم صفر قم بزيادة بزيادة المتحول الذي يشير إلى موضعنا ضمن B.. فقط دون كتابة أي محرف في B
b. عند الوصول إلى هنا سنكون قد أعدنا المحرف المستهدف إلى جميع أماكنه وسننتقل إلى استهداف المحرف التالي ..
7. عندما نصل إلى هنا سنكون قد وضعنا كل حرف في مكانه وستكون الشيفرة قد تم فكّها بالكامل ..اطبع المصفوفة B وانه الخوارزمية...
· تطوير الخوارزمية ...
رأينا أن الخوارزمية قد تنتج شيفرة أكبر من الأصل ب32 مرة في أسوأ الأحوال .. باستثناء الرأس ... باعتباره ثابتاً ...
ولكن رغم ذلك فإن حدود الخوارزمية لا تتوقف على ذلك ... فكل أسلوب في الترتيب ..قد يفتح آفاقاً جديدة ..
وكذلك فإنه من السهل تغيير أسلوب التشفير بحيث يستعصي على الكسر من جهة دخيلة ..
وذلك بتغيير ترتيب الحروف بحيث يمكن أن يعني الترتيب التالي abcd مثلاً .. أن c هو الأول a هو الثاني ثم b ثم d ... وهكذا ..
بعض الملاحظات على تطوير الخوارزمية :
من غير المجدي محاولة تقليص الHeader فطالما أن حجمه ثابت فلا ننظر إليه بعين الاعتبار ..أمام حجم الملف الكلي ...
لاحظنا أن طول الشيفرة يتعلق بشكل مباشر بطريقة ترتيب استهداف المحارف ..وموقع آخر ظهور للمحرف .وطول المصدر
قد يكون التعداد التالي للأفكار مفيداً لمن يرغب في تطوير الخوارزمية :
1. الترتيب حسب أول ظهور للمحرف (ويفيد في تقليل الأصفار على يسار الشيفرة الجزئية)
2. الترتيب حسب آخر ظهور للمحرف (ويفيد في تقليل الأصفار داخل الشيفرة الجزئية)
3. الترتيب حسب تكرار المحرف وهو المستعمل في الخوارزمية السابقة ..
4. تجزئة المصدر إلى عدة أقسام بحيث يتم تشفير كل قسم على حدة(يفيد في حالة تركز كثافة محرف ما أو مجموعة محارف في جزء محدد من المصدر .. أي أن القليل من ملح الذكاء الصنعي في الخوارمية لن يضر)
5. بالنسبة لسلاسل الأصفار الطويلة (بحيث تتجاوز 128بت )يمكن تقليل حجم الشيفرة بشكل ملحوظ ..وذلك بالاستعانة بطول السلسلة بدلاً من كتابتها كما هي .. فبدل كتابة 128بت من الأصفار يمكن أن نكتب الرقم 128 بحيث يحجز 8بت فقط ..وأترك للمطور مهمة تمييز محارف الشيفرة إن كانت لعدد الأصفار أم للأصفار نفسها )
6. قد يكون من المفيد أحياناً أن نستعيض عن الشكل المحرفي للمصدر بالشكل الثماني أو الست عشري ..
فوجود 16 رمزاً أبسط من 256 في بعض الحالات ... وكمقارنة بسيطة ...
شيفرة ب256 محرفاً سيكون طولها 256 *L
شيفرة ب16 محرفاً سيكون طولها 16*2L (ملاحظة :هذه الفكرة خطرت ببالي للتو .. ولم أقم بدراستها )
ختاماً ..شكراً لقراءتكم هذا المقال.. ومشاركتي هذه الفكرة ...هذا برنامج بسيط جداً على الكونسول ..
أولاً ال Coder وهو الذي يقوم بعملية التشفير ... سينتج header ومعه الشيفرة دون تحويلها إلى ASCII
أي أنه سيطبع الأصفار والواحدات كمحارف .. فهدف البرنامج هو إعطاء مثال تجريبي لا أكثر ..
وثانياُ Decoder سيطلب أولا عناصر الHeader واحداُ واحدا ثم يطلب الشيفرة ويقوم بفكها وطباعة الأصل...
يمكن نسخ مخرجات الCoder كما هي ولصقها في الDecoder لتجنب الملل ..exe_only.rar
للقراءة على شكل ملف word Word.rar هذا من فضل ربي ... والحمد لله رب العالمين ...
أرجو ممن يمكنه تطوير الخوارزمية أن يعطيها جزءاً من وقته فقد نصل إلى حلول تغيّر وجه العالم بالتعاون والتواضع ...
والله ولي التوفيق..وله الحمد والشكر والمنة...
والسلام عليكم ورحمة الله وبركاته