مرحبا جميعا!
كل شخص يستخدم الباركود في الوقت الحاضر ، في الغالب دون أن يلاحظ ذلك. عندما نشتري البقالة من المتجر ، فإن معرفاتها تحصل عليها من الباركود. كما هو نفسه مع البضائع في المستودعات والطرود البريدية وهلم جرا. ولكن لا يعرف الكثير من الناس في الواقع ، كيف يعمل.
ما هو "داخل" الباركود ، وما هو المشفر على هذه الصورة؟

يتيح معرفة ذلك ، ويتيح لك أيضًا كتابة وحدة فك ترميز الشريط الخاصة بنا.
مقدمة
باستخدام الباركود لديها تاريخ طويل. بذلت المحاولات الأولى لصنع الأتمتة في الخمسينيات ، وتم منح براءة اختراع نظام قراءة الرموز. ديفيد كولينز ، الذي عمل في ولاية بنسلفانيا للسكك الحديدية ، قرر جعل عملية فرز السيارات أسهل. كانت الفكرة واضحة - لتشفير معرفات السيارة بألوان مختلفة ، وقراءتها باستخدام خلية صور. في عام 1962 أصبحت مثل هذه الرموز القياسية من قبل رابطة السكك الحديدية الأمريكية. (نظام
KarTrak ). في عام 1968 تم استبدال المصباح بالليزر ، حيث سمح بزيادة الدقة وتقليل حجم القارئ. في عام 1973 تم تطوير رمز المنتج العالمي ، وفي عام 1974 تم بيع أول منتج للبقالة (علكة مضغ من ريجلي - كان واضحًا في الولايات المتحدة الأمريكية ؛). في عام 1984 ، استخدم الجزء الثالث من جميع المتاجر الباركود ، وفي بلدان أخرى أصبحت شعبية فيما بعد.
هناك العديد من أنواع الباركود المختلفة للتطبيقات المختلفة ، على سبيل المثال ، يمكن ترميز سلسلة "12345678" بهذه الطرق (وليس كلها):

لنبدأ التحليل. جميع المعلومات الواردة أدناه ستكون حول نوع "Code-128" - لمجرد أنه من السهل فهم المبدأ. يمكن لأولئك الذين يرغبون في اختبار أوضاع أخرى ، استخدام
منشئ الباركود عبر الإنترنت واختبار أنواع أخرى بمفردهم.
للوهلة الأولى ، يبدو الباركود بمثابة مجموعة عشوائية من الأرقام ، ولكن في الحقيقة هيكلها منظم جيدًا:

1 - مساحة فارغة ، مطلوبة لتحديد موضع بدء الشفرة.
2 - رمز البداية. تتوفر ثلاثة أنواع من Code-128 (تسمى A و B و C) ، ويمكن أن تكون رموز البدء هي 11010000100 أو 11010010000 أو 11010011100 على التوالي. بالنسبة إلى هذه الأنواع ، تختلف جداول الترميز (انظر
وصف Code_128 لمزيد من التفاصيل ).
3 - الكود نفسه ، يحتوي على بيانات المستخدم.
4 - التحقق من المبلغ.
5 - رمز الإيقاف ، Code-128 الخاص به 1100011101011.
6 (1) - مساحة فارغة.
الآن دعونا نلقي نظرة ، كيف ترميز البتات. من السهل حقًا - إذا أخذنا أنحف عرض الخط على "1" ، فسيكون خط العرض المزدوج هو "11" ، وخط العرض الثلاثي هو "111" ، وهكذا. ستكون المساحة الفارغة على التوالي "0" أو "00" أو "000" ، وفقًا لنفس المبدأ. يمكن لأولئك المهتمين ، مقارنة تسلسل البداية في الصورة أعلاه ، لمعرفة احترام القاعدة.
الآن يمكننا أن نبدأ الترميز.
الحصول على تسلسل بت
بشكل عام ، الجزء الأكثر تعقيدًا ، ويمكن القيام به بطرق مختلفة. لست متأكدًا من أن مقاربي هي الأفضل ، ولكن لمهمتنا هي بالتأكيد كافية.
أولاً ، يتيح تحميل الصورة ، وتمديد عرضها ، واقتطاع خط أفقي من الوسط ، وتحويله إلى لون b / w وحفظه كصفيف.
from PIL import Image import numpy as np import matplotlib.pyplot as plt image_path = "barcode.jpg" img = Image.open(image_path) width, height = img.size basewidth = 4*width img = img.resize((basewidth, height), Image.ANTIALIAS) hor_line_bw = img.crop((0, int(height/2), basewidth, int(height/2) + 1)).convert('L') hor_data = np.asarray(hor_line_bw, dtype="int32")[0]
على خط الباركود الأسود يتوافق مع "1" ، ولكن في RGB الأسود هو على العكس ، 0 ، لذلك تحتاج إلى عكس المصفوفة. سنقوم أيضا بحساب متوسط القيمة.
hor_data = 255 - hor_data avg = np.average(hor_data) plt.plot(hor_data) plt.show()
يتيح تشغيل البرنامج للتحقق من تحميل الباركود بشكل صحيح:

الآن نحن بحاجة إلى تحديد عرض واحد "بت". للقيام بذلك ، سنقوم باستخراج التسلسل ، مع توفير مواضع عبور الخط المتوسط.
pos1, pos2 = -1, -1 bits = "" for p in range(basewidth - 2): if hor_data[p] < avg and hor_data[p + 1] > avg: bits += "1" if pos1 == -1: pos1 = p if bits == "101": pos2 = p break if hor_data[p] > avg and hor_data[p + 1] < avg: bits += "0" bit_width = int((pos2 - pos1)/3)
نحن نحفظ فقط تقاطعات الخط المتوسطة ، لذلك سيتم حفظ الكود "1101" على أنه "101" ، بت يكفي للحصول على عرض البكسل الخاص به.
الآن دعونا نجعل فك نفسها. نحن بحاجة إلى العثور على كل متوسط عبور خط ، والعثور على عدد البتات في الفاصل الزمني الأخير ، الذي تم العثور عليه. لن تتطابق الأرقام بشكل مثالي (يمكن تمديد الشفرة أو ثنيها قليلاً) ، لذلك ، نحتاج إلى تقريب القيمة إلى عدد صحيح.
bits = "" for p in range(basewidth - 2): if hor_data[p] > avg and hor_data[p + 1] < avg: interval = p - pos1 cnt = interval/bit_width bits += "1"*int(round(cnt)) pos1 = p if hor_data[p] < avg and hor_data[p + 1] > avg: interval = p - pos1 cnt = interval/bit_width bits += "0"*int(round(cnt)) pos1 = p
ربما هناك طريقة أفضل للقيام بذلك ، يمكن للقراء الكتابة في التعليقات.
إذا تم كل شيء بشكل مثالي ، فسنحصل على تسلسل مثل هذا:
11010010000110001010001000110100010001101110100011011101000111011011
01100110011000101000101000110001000101100011000101110110011011001111
00010101100011101011
فك التشفير
بشكل عام ، من السهل جدا. يتم تشفير الرموز في
Code-128 مع رمز 11 بت ، والذي يمكن أن يكون له ترميز مختلف (وفقًا لهذا الترميز - A أو B أو C ، يمكن أن يكون حروفًا أو أرقامًا من 00 إلى 99).
في حالتنا ، بداية التسلسل هي 11010010000 ، والتي تتوافق مع "الرمز B". كنت كسولًا جدًا في إدخال جميع الرموز يدويًا ، لذلك قمت بنسخها من صفحة ويكيبيديا. تم إجراء تحليل لهذه الخطوط أيضًا على Python (تلميح - لا تفعل أشياء مثل هذه في الإنتاج).
CODE128_CHART = """ 0 _ _ 00 32 S 11011001100 212222 1 ! ! 01 33 ! 11001101100 222122 2 " " 02 34 " 11001100110 222221 3 # # 03 35 # 10010011000 121223 ... 93 GS } 93 125 } 10100011110 111341 94 RS ~ 94 126 ~ 10001011110 131141 103 Start Start A 208 SCA 11010000100 211412 104 Start Start B 209 SCB 11010010000 211214 105 Start Start C 210 SCC 11010011100 211232 106 Stop Stop - - - 11000111010 233111""".split() SYMBOLS = [value for value in CODE128_CHART[6::8]] VALUESB = [value for value in CODE128_CHART[2::8]] CODE128B = dict(zip(SYMBOLS, VALUESB))
الأجزاء الأخيرة سهلة. أولاً ، يتيح تقسيم التسلسل إلى كتل 11 بت:
sym_len = 11 symbols = [bits[i:i+sym_len] for i in range(0, len(bits), sym_len)]
أخيرًا ، يتيح إنشاء سلسلة الإخراج وعرضها:
str_out = "" for sym in symbols: if CODE128A[sym] == 'Start': continue if CODE128A[sym] == 'Stop': break str_out += CODE128A[sym] print(" ", sym, CODE128A[sym]) print("Str:", str_out)
لن أعرض هنا النتيجة التي تم فك تشفيرها من الصورة العليا ، فليكن ذلك واجباً للقراء (سيتم اعتبار استخدام التطبيقات التي تم تنزيلها للهواتف الذكية الغش :).
لم يتم تنفيذ اختبار CRC في هذا الرمز ، أولئك الذين يريدون ، يمكنهم القيام بذلك بأنفسهم.
بالتأكيد ، هذه الخوارزمية ليست مثالية ، لقد تم ذلك في نصف ساعة. بالنسبة للمهام الاحترافية ، توجد مكتبات جاهزة للاستخدام ، على سبيل المثال ،
pyzbar . لفك تشفير الصورة ، 4 أسطر من الرموز تكفي:
from pyzbar.pyzbar import decode img = Image.open(image_path) decode = decode(img) print(decode)
(يجب أولاً تثبيت المكتبة باستخدام أمر "pip install pyzbar")
إضافة : أرسل مستخدم الموقع
vinograd19 تعليقًا مثيرًا للاهتمام حول تاريخ حساب مجموع الباركود.
حساب رقم الشيك مثير ، نشأ تطوريًا.
من الواضح أن هناك حاجة إلى التحقق من المبلغ لتجنب فك التشفير الخاطئ. إذا كان الرمز الشريطي 1234 ، وتم فك تشفيره على أنه 7234 ، فنحن بحاجة إلى طريقة لرفض استبدال الرقم 1 إلى 7. قد لا يكون التحقق من الصحة مثاليًا ، ولكن يجب التحقق من 90٪ على الأقل من الرموز بشكل صحيح.
الطريقة الأولى: دعنا نأخذ المبلغ ، لنحصل على 0 كباقي التقسيم. تحتوي الرموز الأولى على بيانات ، والرقم الأخير هو ، بحيث يتم تقسيم مجموع جميع الأرقام على 10. بعد فك التشفير ، إذا كان المبلغ غير قابل للقسمة على 10 - فك التشفير غير صحيح ، ويجب تكراره. على سبيل المثال ، الرمز 1234 صالح - 1 + 2 + 3 + 4 = 10. الرمز 1216 - صالح أيضًا ، لكن 1218 غير صالح.
إنها تساعد على تجنب مشاكل فك التشفير. ولكن يمكن أيضًا إدخال الرموز يدويًا باستخدام لوحة مفاتيح الأجهزة. باستخدام هذا ، تم العثور على حالة سيئة أخرى - إذا كان سيتم تغيير ترتيب مكون من رقمين ، فسيظل مبلغ الشيك صحيحًا ، وسيئ بالتأكيد. على سبيل المثال ، إذا تم إدخال الرمز الشريطي 1234 كـ 2134 ، فسيكون مبلغ التحقق هو نفسه. تم العثور على أن ترتيب الأرقام الخاطئ كان هو الحالة الشائعة ، إذا كان الشخص يحاول إدخال الأرقام بسرعة.
النهج الثاني. يتيح تحسين خوارزمية المجموع الاختباري - يتيح حساب الأرقام الفردية مرتين. ثم ، إذا تم تغيير الطلب ، فسيكون المجموع غير صحيح. على سبيل المثال ، الكود 2364 صالح (2 + 3 * 2 + 6 + 4 * 2 = 20) ، لكن الكود 3264 غير صالح (3 + 2 * 2 + 6 + 4 * 2 = 19). لها أفضل ، ولكن ظهرت قضية أخرى. هناك بعض لوحات المفاتيح ، تحتوي على 10 مفاتيح في صفين ، الصف الأول هو 12345 والثاني هو 67890. إذا كان المستخدم يكتب "2" بدلاً من "1" ، فسوف يفشل التحقق من المجموع الاختباري. ولكن إذا كان المستخدم سوف يدخل "6" بدلاً من "1" - فقد يكون المبلغ الصحيح في بعض الأحيان. نظرًا لأن 6 = 1 + 5 ، وإذا كان للرقم مكانًا فرديًا ، فسنحصل على 2 * 6 = 2 * 1 + 2 * 5 - زاد المجموع بمقدار 10. وسيحدث نفس الخطأ ، إذا كان المستخدم سوف يدخل "7 "بدلاً من" 2 "،" 8 "بدلاً من" 3 "، وهكذا.
النهج الثالث. لنأخذ المبلغ مرة أخرى ، ولكن لنحصل على أرقام غريبة ... 3 مرات. على سبيل المثال ، الرمز 1234565 - صالح ، لأن 1 + 2 * 3 + 3 + 4 * 3 + 5 + 6 * 3 +5 = 50.
أصبحت هذه الطريقة معيارًا لرمز EAN13 ، مع بعض التغييرات: عدد الأرقام ثابت ويساوي 13 ، حيث الرقم 13 - هو مبلغ الشيك. يتم حساب الأرقام في الأماكن الفردية ثلاث مرات ، وحتى في الأماكن مرة واحدة.بالمناسبة ، رمز EAN-13 هو الأكثر استخدامًا على نطاق واسع في مراكز التسوق والتسوق ، لذلك يرى الناس ذلك كثيرًا أكثر من أنواع الأكواد الأخرى. تشفيره هو نفسه كما في Code-128 ، يمكن العثور على بنية البيانات في
مقالة ويكيبيديا .
الخاتمة
كما يمكننا أن نرى ، حتى أن الأمر السهل مثل الباركود ، يمكن أن يحتوي على بعض الأشياء الرائعة. بالمناسبة ، هناك حيازة صغيرة أخرى للقراء ، الذين كانوا صبورين بما يكفي للقراءة حتى هذا المكان - النص الموجود تحت الباركود مطابق تمامًا لبيانات الباركود. تم إعداده للمشغلين الذين يمكنهم إدخال الرمز يدويًا ، إذا لم يكن قابلاً للقراءة بواسطة الماسح الضوئي. لذلك من السهل معرفة محتوى الباركود - فقط اقرأ النص أدناه.
شكرا للقراءة.