.

Застосування штрих-коду для кодування інформації (дипломная)

Язык: украинский
Формат: дипломна
Тип документа: Word Doc
215 12786
Скачать документ

ДИПЛОМНА робота

застосування штрих-коду для кодування інформації

ЗМIСТ

Вступ 3

1. Теоретичні відомості

1.1 Побудова та класифікація штрихових кодів 5

1.2 Деякі поняття теорії інформації 7

1.2.1 Міра інформації 7

1.2.2 Інформаційна ентропія 10

1.2.3 Умовна ентропія. Iнформацiя, що мiститься в одному дослiдi
вiдносно iншого 13

1.2.4 Надлишковість 17

1.2.5 Цiннiсть iнформацiї 19

1.2.6 Экспоненциальный закон збiльшення числа

повiдомленнь 20

1.3 Коди з виявленням та виправленням помилок 22

1.3.1 Кодування інформації 22

1.3.2 Коди з виявленням та виправленням помилок 24

2. Огляд найбільш вживаних типів штрихових кодів

2.1 Загальний огляд 28

2.2 Тип EAN-13, UPC та EAN-8 31

2.3 Code39 та CODABAR 35

2.4 INTERLEAVED 2 OF 5 38

3. Створення самокорегуючого штрихового коду

3.1 Постановка задачі 40

3.2 Хід роботи 40

4. Результати та їх аналіз

4.1 Початкові результати 46

4.2 Кінцевий результат 46

5. Програми

5.1 Iнструкція користувача 48

5.2 Текст програм 53

Висновки 99

Джерела 100

ВСТУП

За останні півтора-два десятиліття штрихові коди щільно увійшли в наше
життя, зараз ми зустрічаємо їх в повсякденному житті на кожному кроці.
Їх можна побачити на харчових продуктах в крамниці, на поштових
конвертах та бандеролях, ними маркують коробки на складах та різного
роду посвідчення особи.

Сфера застосування штрихових кодів надзвичайно широка і вона весь час
розширюється, але не зважаючи на це для більшості пересічних громадян ці
чорні та білі смужки залишаються незрозумілими.

Широке використання штрихових кодів було зумовлене необхідністю
забезпечити автоматизоване введення інформації в комп’ютерні системи
управління, що відрізнялося б високою надійністю, простотою і
економічністю. Штриховий код — це не щось особливе, існуюче саме по
собі, а передусім елемент системи управління. В відриві від комп’ютерної
системи управління, поза зв’язком з її інформаційною базою він не має
жодного сенсу. Технологія штрихового кодування застосовується в багатьох
сферах людської діяльності, але найбільш широко і ефективно вона
використовується в оптовій і роздрібній торгівлі, управлінні
матеріальними запасами, управлінні перевезеннями. Ми стикаємось зі
штриховыми кодами, купуючи товар в крамницях, здаючи багаж в
аеропортах… Цей список можна продовжити, але вже наведених прикладів
достатньо, щоб переконатися, що потреба в їхньому виготовленні значна.

Чому саме штрихові коди вийшли на перше місце серед безлічі відомих
засобів ідентифікації? Що зумовило їхню перевагу в більшості практичних
додатків перед іншими оптичними засобами, не говорячи вже про такі, як
магнітні або, скажемо, пов’язані з застосуванням радіоізотопів? Як вже
було сказано, переваги різних засобів оцінюються з точки зору
надійності, простоти застосування і економічності. Штрихові коди
характеризуються високою надійністю. До них застосовні ті засоби захисту
від помилок, що широко використовуються в зв’язку та комп’ютерній
справі. За рахунок деякої надмірності можна створювати самоконтролюючі і
самокорректуючі коди, тобто такі, що здатні шляхом перевірки по
спеціальним алгоритмам забезпечити відшукання помилок і навіть їх
автокоррекцію за умови, що кількість помилкових знаків в коді не
перевищує встановленої межі (звичайно 65-70%). При існуючих засобах
захисту лінійного коду, що забезпечують імовірність помилки не більш
однієї на 30 млн. зчитаних знаків, надмірність коду залишається в
розумних межах — звичайно це одна контрольна цифра.

Простота застосування штрихового коду визначається його природою: його
наявність чи відсутність одразу видно (на відміну від магнітних або
радіохвильовх засобів, що застосовуються передусім там, де вміст і
навіть присутність коду бажано приховати), він легко розміщується на
упаковці виробу або на паперовому етікетці, добре зчитується приладами,
з’єднаними з комп’ютером. При цьому такі прилади не є складними в
проектуванні та виробництві, будучи різновидністю звичайних сканерів.

По економічності технологія штрихового кодування не має собі рівних,
навіть в виробництві дешевих товарів масового попиту, виготовлення
штриховых кодів не має помітного впливу на собівартість товару для
виробника.

В залежності від потреб створено велику різноманітність типів штрихових
кодів. Кожна конкретна область застосування цих кодів формулює власні
вимоги до них. Так в одному випаду головною умовою є простота коду,
можливість легкого його читання навіть людиною, в інших вимагається
висока щільність інформації на одиниці площі штрихового коду. Якщо при
використанні деякого штрихкоду у нас немає змоги зіскановувати його по
декілька разів, наприклад при швидкій автоматизованій обробці
інформації, тоді до такого типу штрихкоду головною вимогою є надійність
закодованої інформації.

Звичайно ж надійність інформації, закодованої тим чи іншим способом,
важлива завжди, але різні характеристики коду нерідко обернено-залежні.
Тому нам доводиться в тій чи іншій мірі жертвувати надійністю,
наприклад: при спробі збільшити кількість інформації на одиницю площі
штрихового коду.

В цій дипломній роботі було розвязано задачу по максимізації надійності
штрихового коду. Було створено ефективний код, здатний запобігати
неправильному зчитуванню закодованої інформації. Це було зроблено за
допомогою використання матода Хеммінга при побудові штрихового коду.
Необхідно зазначити, що подібних типів штрихових кодів в світі на даний
момент не існує, а його надзвичайну ефективність буде продемонстровано
згодом. Також в ході виконаня цієї дипломної роботи було розглянуто
різноманітні методи побудови штрихових кодів, а також проаналізовано та
порівняно найчастіше уживані їх типи.

1. Теоретичні відомості

1.1. CПОСОБИ ПОБУДОВИ ШТРИХОВИХ КОДІВ ТА МЕТОДИ КЛАСИФІКАЦІЇ

Розглянемо основнi принципи та правила, що використовуються про
створеннi штрихових кодiв i якi є обов’язковими для будь-якого їх типу.
Одразу потрiбно зазначити, що інформація яку ми кодуемо представлена в
двійковому виді, тобто кодується двома значеннями: ‘0’ та ‘1’. В
штриховому кодуванні існує два способи задання цих значень, першим є
спосіб, коли значення ‘0’ та ‘1’ кодуються відповідно двома кольорами –
білим та чорним. Наприклад: бітова послідовність 10110011101100011 буде
мати слідуюче штрихове представлення:

(рис1)

В цьому способі штрихи що відповідають ‘0’ та ‘1’ мають одинакову
ширину. В разі якщо в бінарній послідовності йдуть одне за одним кілька
одинакових n значень ‘0’ чи ‘1’ їм буде відповідати білий чи чорний
штрих n-кратної ширини.

Другим способом представлення бітової послідовності в виді штрихового
коду є спосіб коли ‘0’ та ‘1’ задані не різними кольорами, а різними
значеннями ширини штрихів. Тобто маємо чотири атомарні графічні символи
два вузькі штриха та два широкі білого та чорного кольорів. В такому
штриховому коді білі та чорні штрихи весь час йдуть почергово, а
значенням ‘0’ та ‘1’ відповідають відповідно широкі та візькі штрихи. В
цьому разі наведена вище бінарна послідовність буде мати вигляд:

(рис2)

В кожному з цих варіантів є як переваги так і недоліки. Так в першому
варіанті штриховий код буде коротшим в наслідок того, що всі біти
кодуються однаковими по ширині штрихами. По цій самій причині в першому
варіанті штриховий код бінарної послідовності зі сталим числом бітів
буде мати сталий розмір, в той час як в другому варіанті розмір
штрихового коду буде залежати від співвідношення нулів та одиниць. Але
недоліком першого варіанту є те, що при великій кількості йдучих один за
одним одинакових бітів їх графічне представлення може неправильно
тлумачитися. Так, наприклад буде важко розрізнити штрихкоди для 100001
та для 1000001.

В залежності від конкретних задач кожен з цих способів кодування
знаходить своє примінення і його недоліки або просто ігноруються, або
виправляються в той чи інший спосіб. Пізніше ми розглянемо ці способи на
конкретних типах штрихових кодів.

(рис3) (рис4)

Розглянемо інші особливості побудови штрихових кодів, які також
використовуються для класифікації штрихових кодів. Однією з таких
особливостей є наявність чи відсутність контрольних штрихів(бітів). Вони
використовуються в разі потреби стабілізації швидкості зчитування нашого
коду від початку до кінця. В випадку відсутності контрольних штрихів,
при нерівномірній швидкості зчитування штрихкоду, цей код можливо буде
інтерпретовано неправильно. Щоб цьому запобігти, на початку та в кінці
нашого коду розміщується набір з принаймні двох контрольних штрихів.
Після зчитування ЕОМ цього коду, обчислювальна машина може судити про
зміну швидкості сканування штрихового коду і відповідно корегувати
процес декодування. Прикладом застосування контрольних штрихав може бути
штриховий код типу EAN-13. В ньому контрольні штрихи наявні не тільки на
початку та в кінці, а і в середині коду.

(рис5)

Детально даний тип штрихового коду буде розглянуто пізніше.

Ще однією особливістю при побудові штрихового коду є наявність чи
відсутність контрольної суми. Для гарантування правильності декодування
штрихового коду в деяких типах штрихового коду до інформації, що
кодіється додається деяка контрольна сума яка функціонально залежить від
кодованої інформації. Ця контрольна сума кодується в штриховий код разом
з основною інформацією, а при декодуванні ЕОМ знову вираховує контрольну
суму цього коду і порівнює з заданим. Зрозуміло що в разі неспівпадання
цих двох контрольних сум штриховий код був не правильно зіскановано.

В наслідок використання всіх цих додаткових засобів надійності
штрихового коду, виникає питання, а скільки справді корисноі інформації
несе той чи інший штриховий код? Яким буде в ньому відношення кількості
допоміжної контрольної інформації до справді корисної – тієї котру ми
хотіли кодувати? Щоб відповісти на це питання, вводять поняття ентропії,
міри інформації та надлишковості.

1.2 Деякі поняття теорії інформації

1.2.1 Мiра iнформацiї

Кожне повiдомлення, кожна iнформацiя про той або iнший фактi має немов
би двi сторони: конкретний змiст даного повiдомлення, даного факту, i
статистичнi (ймовiрноснi) властивостi, що дозволяють порiвнювати цiлком
разнорiднi повiдомлення по тій різноманітності станiв, з якими цi
повiдомлення зв’язанi.

Наприклад, повiдомлення про те, що в технiчнiй системi управлiння
вийшов з ладу один з двох однаково надiйних (або, краще сказати,
ненадiйних) підсилювачів, i повiдомлення, що Н. народила хлопчика,
зв’язанi з однiєю i тіею же різноманітністю – з появою одного з двох
рівноможливих фактiв.

В сенсi зв’язаної з цими фактами різноманітності цi два повiдомлення
цiлком однаковi, хоча їхнiй конкретний змiст iстотно різниться.
Відмічена нами спiльнiсть має далеко iдучі наслiдки, а саме: як ми
побачимо нижче, ефективнi системи зв’язку для передачi повідомлень
одного типу будуть настiльки ж хороші i для передачi вiдомостей другого
типу. Ця спiльнiсть i дозволяє ввести деякi загальнi поняття, зв’язанi з
рiзноманiтними повiдомленнями, незважючи на їхню різнорідність. Таким
поняттям, що висловлює мiру різноманітності ситуацiї, зв’язаної з тим
або iншим повiдомленням або фактом, є iнформацiя.

Вiдзначимо, що поняття кiлькостi iнформацiї, укладеної в тому або
iншому повiдомленнi, зв’язане з iмовiрнiстю цього повiдомлення, тобто з
деякою статистичною сукупнiстю. Введемо бiльш точне визначення
iнформацiї як деякої кiлькiсної величини – деякої мiри.

По визначенню кiлькiсть власної iнформацiї, укладеної в повiдомленнi Аi
рiвна логарифму його iмовiрностi, взятому зі зворотнім знаком

I (Аі) = -log(P(Ai)). (1.14)

Знак мiнус в формулi (1. 14) введений для того, щоб зробити цей вираз
iстотно позитивним [0?Р(Аi)?1, ? логарифм Р (Ai) – величина вiдємна].
Виразу (1. 14) можна придати вигляд

I(Аi)=log 1/P(Ai) (1.15)

з якого слiдує, що чим менша iмовiрнiсть появи повiдомлення Ai, тим
бiльшою кiлькiстю iнформацiї воно володiє.

Сенс вводу логарифмичної мiри в виразах (1.14) i (1.15) полягає в
наданнi кiлькостi iнформацiї властивостi адитивності. Справдi, якщо ми
маємо дiло зi складним повiдомленням, що полягае в одночасному
повiдомленнi двох фактiв Ai i Вj, i якщо цi факти (подiї) незалежнi в
iмовiрносному розумiннi, то, згiдно (1. 14),

I (A, Bj) = logP (Ai(Bi).

Або, застосовуючи теорему про множення iмовiрностей, маємо

I(Аi,Bj) = – log[ Р(Аi)Р(Bj)] = -1оg Р(Ai) – log P(Вj) = I(Ai) – I(Bj).
(1.16)

Іншими словами, кiлькiсть iнформацiї, вкладеної в два незалежних
повiдомлення, рiвна сумi кiлькостi iнформацiї, вкладеної в кожне
повiдомленнi. З наведеного вище визначення власної iнформацiї (1. 14)
слiдує надто важливий висновок: з деяким повiдомленням Аi можна зв’язати
поняття власної iнформацiї тiльки в тому випадку, якщо iснує поняття
iмовiрностi цього повiдомлення (тобто, якщо його можна зв’язати з деяким
статистичним ансамблем). Наприклад, окреме повiдомлення, не зв’язане з
якою-небуть рiзноманiтнiстю, не володiє в розумiннi теорiї iнформацiї
поняттям власної iнформацiї.

Можуть зустрiтися повiдомлення, що хоча i утворюють статистичну
рiзноманiтнiсть, але не володiючi iмовiрнiстю внаслiдок нестационарностi
випадкового механiзму. Наприклад, якщо ми пiдкидуємо абсолютно тверду
монету, то випадковий механiзм випадання орла або решки стацiонарний, i
обидва повiдомлення – випадання орла або решки – володiють iмовiрнiстю,
що в цьому випадку рiвна половинi. Якщо же ми будемо пiдкидувати м’яку
монету, то випадання орла або решки також буде випадковою подiєю. Однак
випадковий механiзм вже не буде стацiонарний внаслiдок деформацiї
монети. При цьому частота випадення, наприклад орла (або решки), зi
збiльшенням числа кидання не буде прагнути до певної межi. Значить, з
таким випадковим процесом не можна зв’язати поняття iмовiрностi (тут не
дiє закон великих чисел). Отже, такi подiї (повiдомлення) не володiють
iнформацiєю в сенсi (1.14).

Ця обставина має цiлком ясний фiзичний зміст: якщо в основi появи
повiдомленнi на входi деякого каналу зв’язку не лежить стацiонарний
випадковий механiзм, тобто для них не iснує поняття iмовiрностi, то
випадковiсть такого типу не може бути нiяк завбачена, i для таких
повiдомлень заздалегiдь неможливо побудувати оптимальний канал зв’язку.

Коли ми говоримо про оптимальнiсть, то маємо на увазi погодження
пропускної спроможностi каналу з кiлькiстю iнформацiї, укладеною в
повiдомленнях, що надходять на вхiд канала.

Може виявитися, що нестационарнiсть випадкового механiзму пiдкоряється
певному закону. В цьому випадку iмовiрнiсть появи повiдомлень буде
функцiєю часу. Для таких повiдомлень має мiсце поняття власної
iнформацiї, що в цьому випадку також буде функцiєю часу.

Нарештi, може трапитися, що з системою повiдомлень можна зв’язати
поняття iмовiрностi i, значить, кожне повiдомлення володiє власною
iнформацiєю, але ми не знаємо цих iмовiрностей. В такому випадку ми
також спочатку нiчого не можемо сказати про кiлькiсть iнформацiї, що
несе в собi те або iнше повiдомлення. I тiльки з течiєю часу, пiсля
надходження на вхiд канала достатньо великої кiлькостi повiдомлень,
збирається необхiдна статистика, що дозволяє встановити кiлькiсть
iнформацiї, зв’язану з кожним повiдомленням.

В технiчному сенсi це означає, що не можна заздалегiдь сконструювати
хорошу систему (принаймнi в планi лiнiї зв’язку). Але ми маємо
можливiсть будувати, самонавчальну систему, що адаптується, що з течiєю
часу, з’ясовуючи iстинну статистику розподiлу повiдомлень, тобто
визначаючи кiлькiсть iнформацiї, зв’язане з тим або iншим повiдомленням,
зможе себе змiнювати, покращувати. Наприклад (в граничному випадку), по
якому-небуть каналу надходить весь час одне i те ж повiдомлення А. В
цьому випадку система визначить, що Р (А)=1 i, отже, I=0. Значить, можна
просто запам’ятати це повiдомлення, а канал зв’язку вимкнути. Це i буде
простим прикладом адаптацiї.

Другим важливим поняттям є вiдносна iнформацiя одного повiдомлення Sj
вiдносно iншого Ai. Сенс цього поняття полягає в тому, що надходження
деякого факту (повiдомлення Sj) може змiнити статистичну
рiзноманiтнiсть, зв’язану з повiдомленням Аi, i внаслiдок цього власну
iнформацiю повiдомлення Аi. Змiна власної iнформацiї повiдомлення Aі, що
виникла через надходження повiдомлення Sj, i називається вiдносною
iнформацiєю повiдомлення Sj вiдносно Ai.

Нехай iмовiрнiсть повiдомлення Аi до надходження повiдомлення Sj рiвна
Р(Аi). Тодi кiлькiсть власної iнформацiї, укладеної в повiдомленя Ai,
рiвне

I (Ai) = -log P(Ai).

Iмовiрнiсть повiдомлення Аi, пiсля надходження повiдомлення Sj буде
рiвна Psj(Аi), тобто являє собою умовну iмовiрнiсть Ai за умови, що Sj
має мiсце. При цьому кiлькiсть iнформацiї, що мiститься в надходженнi
повiдомлення Ai, рiвна

I (Ai/Sj) = – log Psj(Ai).

Тодi по визначенню iнформацiя, що мiститься в Sj вiдносно Аi, рiвна
змiнi (зменшенню) власної iнформацiї повiдомлення Ai:

Isj(Ai) = I(Ai) – I(Ai/Sj) = – log P(Ai)+ log Psj(Ai) =
log(Psj(Ai)/P(Ai)). (1.17)

Це нове поняття вiдносної iнформацiї зв’язане не з iмовiрнiстю
повiдомлення Sj, а зi змiстом цього повiдомлення, бо саме конкретний
змiст повiдомлення Sj визначає умовну iмовiрнiсть подiї Аi (Psj(Ai)).
Таким чином, вiдносна iнформацiя деякого повiдомлення Sj зв’язана саме з
його змiстом, а не з його власною рiзноманiтнiстю, якої може i не бути.
Таким чином, навiть з окремим повiдомленням, не зв’язаним з поняттям
iмовiрностi, можна зв’язати поняття iнформацiї вiдносно iншої
рiзноманiтностi, якщо воно цю рiзноманiтнiсть змiнює.

В протилежнiсть власнiй iнформацiї, вiдносна iнформацiя може бути не
тiльки позитивною, але i негативною. Якщо Psj(Ai) > Р(Аi), то, згiдно
(1.17), Isj(Аi)=0; якщо Psj(Ai) < P(Ai), то Isj(Ai) Psj(Ai)=P(Ai) Isj(Аi)=0. Останнiй випадок означає, що повiдомлення Sj не
змiнює рiзноманiтностi Ai i, отже, не мiстить в собi iнформацiї вiдносно
повiдомлення Ai. Повертаючись до основної iнформацiйної мiри, до виразу
(1.14), легко бачити, що числова величина його залежить вiд вибору
основи логарифмування. Звичайно в теорiї iнформацiї в якостi основи
беруть число 2; тодi числова величина кiлькостi iнформацiї, укладеної в
деякому повiдомленнi Ai, рiвна

Ii=log2 Рi. (1. 18)

В подальшому викладеннi для спрощення письма ми будемо опускати в записi
логарифма iндекс 2, маючи на увазi, що скрiзь, за винятком спецiально
обумовлених випадкiв, ми будемо мати справу з логарифмом при цiй основi.
Припустимо, ми отримали повiдомлення, iмовiрнiсть якого рiвна половинi.
Тодi таке повiдомлення володiє кiлькiстю iнформацiї

Ii=log2 (1/2) =1 двiйкова одиниця = 1бiт.

Отже, це повiдомлення володiє однiєю двiйковою одиницею iнформацiї
(двiйковою тому, що в якостi основи логарифма прийняте число 2) або, як
часто говорять, несе 1 бim iнформацiї (б – bit, binary digit). В якостi
дiйкової одиницi iнформацiї, приймається та кiлькiсть iнформацiї, що
полягає в повiдомленi про те, що вiдбулися одне з двох рiвноможливих
подiй (наприклад, iнформацiя про те, що при даному пiдкидуваннi монети
випав герб).

Уявимо собi далi, що деякий дослiд може закiнчитися одним з чотирьох
рiвноможливих наслiдкiв. Тодi повiдомлення про те, що має мiсце деякий
конкретний наслiдок, володiє iмовiрнiстю Pi=l/4. Вiдповiдно кiлькiсть
iнформацiї в цьому повiдомленнi J = – 1оg(1/4)=2 бiт. Якщо ж ситуацiя
дослiду настiльки невизначена, що може з’явитися будь-який з 64
рiвноможливих наслiдкiв, то кiлькiсть iнформацiї, укладеної в
повiдомлення про деякий конкретний наслiдок, рiвна J = – log(1/64) = 6
бiт i т. д.

Вже з цих прикладiв видно, що кiлькiсть iнформацiї в даному конкретному
повiдомленнi тим бiльша, чим бiльша невизначенiсть ситуацiї. Як побачимо
нижче, iснує дуже тiсний зв’язок мiж iнформацiєю i невизначенiстю, i що
кiлькiсть власної iнформацiї може служити мiрою невизначеностi ситуацiї.

На кiнець розглянемо приклад. По каналу зв’язку передається пятизначне
двiйкове число так, що в кожному розрядi може стояти цифра 0 або 1 з
рiвною iмовiрнiстю, i поява тiєї або iншої цифри в даному розрядi не
залежить вiд цифр що стоять в iнших розрядах. Визначимо, яка кiлькiсть
iнформацiї мiститься в деякому числi ,що передається. Нехай для
визначеностi дано число ,що передає значення 10110. Тодi iмовiрнiсть
появи даного числа Ai = Рi = (1/2)5 (згiдно теоремi множення
iмовiрностей). Легко бачити, що будь-яке число ,що передається володiє
тiєю ж iмовiрнiстю. Тодi кiлькiсть iнформацiї, укладена в кожне число
,що передається, рiвна

I = – log Pi = – log (1/2)5= 5 бiт.

Вiдповiдно при передачi n-розрядного двiйкового числа, кiлькiсть
iнформацiї на повiдомлення рiвна I = n бiт.

З прикладу видно, що при двiйковому кодуваннi повiдомлень дуже зручно
застосовувати при обчисленнi кiлькостi iнформацiї логарифм з основою
два.

Iнформацiйна ентропія

До цих пiр ми розглядали кiлькiсть власної iнформацiї, що мiститься в
даному конкретному повiдомленнi Ai, i для нього ввели мiру iнформацiї
(1. 14) Ii = – log Pi. Уявимо собi тепер, що в результатi проведення
деякого дослiду можливi k рiзноманiтних повiдомлень (результатiв дослiду
А1, А2, …, Ak). Цей дослiд ми повторюємо велике число раз (n),
наприклад n раз передаємо повiдомлення з даної вхiдної системи, i нехай
з цих повiдомлень (результатiв) А1 повторюється m1 раз, А2 повторюється
m2 раз i т. д. Крiм того, нехай iмовiрностi повiдомлень А1, А2, …, Ak
вiдповiдно рiвнi Р1, P2, …, Рk. Тодi середня власна iнформацiя на одне
повiдомлення буде рiвна сумi iнформацiї, подiлленої на кiлькiсть
повiдомлень ,що передаються, або середня власна iнформацiя на одне
повiдомлення рiвна

(- m1 logP1 – m2 logP2 – … -mk logPk)/n.

Очевидно, межа цього вираження при n?? рiвна

k

H = – ??Pi log Pi , (1. 19)

1

бо в вiдповiдностi з законом великих чисел

при n?? lim (mi/n)=Pi.

Вираз (1.19) являє собою середню власну iнформацiю на одне повiдомлення
(на один результат дослiду) i називається iнформацiйною ентропiєю
ситуацiї (дослiду) або просто ентропією. Поняття ентропiї надзвичайно
важливе в теорiї iнформацiї, i щоб яснiше уявити фiзичний сенс цiєї
величини, розглянемо деякi властивостi ентропiї.

1. Ентропiя завжди додатня

Н ??0. (1. 20)

Дiйсно, 0 ??Pi ??1, тому log Pi?0, тобто величина вiдємна. Отже,
враховуючи знак мiнус в виразi (1. 19), кожний член цiєї суми буде
додатнiм, а отже, i вся сума додатня.

2. Ентропiя рiвна нулю в тому i тiльки в тому випадку, якщо iмовiрнiсть
одного з результатiв рiвна одиницi, а отже, iмовiрностi всiх iнших
результатiв рiвнi нулю (нагадаємо, що P1+P2+… +Pk=1). Iншими словами,
ентропiя рiвна нулю, тодi коли ситуацiя повнiстю визначена, тобто
результат дослiду заздалегiдь передбачено.

Дiйсно, вираз (1. 19) являє собою суму додатніх величин, тому ця сума
може бути рiвна нулю тiльки в тому випадку, коли кожний з її членiв Р
log P рiвний нулю. Вираз Р logР рiвний нулю або при Р=1 (що очевидно, бо
при Р=1 логарифм Р рiвний 0), або при Р=0. В останньому випадку має
мiсце невизначенiсть, i щоб її розкрити, запишемо вираз Р logР в виглядi

PlogP= (logP)/(1/P).

Границя цього виразу рiвна межi вiдношення похiдної числiвника до
похiдної знаменника

Але тiльки один результат дослiду може володiти iмовiрнiстю, рiвною
одиницi, i при цьому всi iншi результатi володiють iмовiрнiстю, рiвною
нулевi, тому сума (1. 19) рiвна нулю тiльки в цьому випадку i наше
твердження доведене.

3. Ентропiя максимальна тодi i тiльки тодi, коли всi результати
ситуацiї (дослiду) рiвноможливi. Припустимо, що наша ситуацiя може мати
k результатов i всi вони рiвноможливi. Тодi Р1 = Р2.. = Рk = 1/k,
оскiльки Р1+P2+…+Рk=1. При цьому значення ентропiї в вiдповiдностi з
(1. 19) буде рiвне

Hmax=log k . (1. 21)

Покажемо тепер, що ентропiя завжди менша або рiвна виразу (1. 21). Для
цього складемо рiзницю

k

H – log k = – ??Pi log Pi – log k =

1

k k
k

= – ??Pi log Pi – ??Pi log k = – ??Pi log 1/Pi ,

1 1
1

k

оскiльки ??Pi =1.

1

Скористаємось далi наступною властивiстю логарифмiчної функцiї: для
будь-якого значення аргументу w має мiсце нерiвнiсть

ln w ( w-1. (1. 23)

Нерiвнiсть (1. 23) (в лiвiй частинi стоїть натуральний логарифм)
очевидно з рис. 5. Знак рiвностi має мiсце при значеннi w=1. Якщо в
правій частинi (1. 22) величину 1/Рik позначимо через w i приймемо до
уваги, що

log w = ln w log e,

то можна до кожного члена суми (1. 22) застосувати нерiвнiсть (1. 23).
Тодi отримаємо

Оскiльки

то

H – log k ??0 (1.24)

Таким чином, ентропiя завжди менша або рiвна величинi log k (1.22),
причому знак рiвностi має мiсце при w=1, тобто при 1/Pik=1, або при всiх
Pi=1/k, що означає рiвноможливiсть всiх результатiв дослiду.

З другої i третьої властивостей слiдує, що ентропiя рiвна нулю, коли
ситуацiя повнiстю визначена, тобто результат дослiду заздалегiдь
передбачено, i максимальна при найбiльшiй невизначенностi ситуацiї, коли
всi можливi результатi дослiду рiвноможливi. Таким чином, ентропiя в
принципі є мiрою невизначеностi ситуацiї i вона тим бiльша, чим бiльша
ця невизначенiсть.

Всяке впорядкування ситуацiї, збiльшення її визначенностi зменшує
ентропiю. Отже, вираз (1. 19), з одного боку, являє собою середню
iнформацiю, яку можна очiкувати вiд повiдомлення в даних умовах, а з
iншого, його можна розглядати, як мiру невизначеностi ситуацiї. Цi двi
сторони, звичайно, зв’язанi мiж собою. Справдi, чим бiльш невизначена
ситуацiя, тим бiльша iнформацiя буде полягати в кожному повiдомленнi про
який-небуть конкретний результат. Часто в результатi деякого дослiду ми
одержуємо деяку кiлькiсну величину х, що може приймати будь-яке значення
в заданому iнтервалi. В цьому випадку результатом дослiду є безперервна
випадкова величина, що володiє деяким законом розподiлу p (x) (рис. 6).

рис.5 рис.6

Отже, тут ми маємо дiло з нескiнченним числом можливих результатов i
значить з нескiнченним числом можливих повiдомлень. Для такої ситуацiї
по аналогiї з виразом (1.19) вводиться поняття ентропiї безперервного
розподiлу

+?

-??p(x) log p(x) dx (1. 25)

-?

1.2.3 Умовна ентропія. Iнформацiя, що мiститься

в одному дослiдi вiдносно iншого

Розглянемо два дослiди а i b, вiдповiдно з результатами А1, A2, …,
Аi, …, Am i результатами В1, B2, …, Вj, …, Bn i вiдомими
iмовiрностями цих результатів Р(А1), Р(А2), …, Р(Ai) i Р(В1), Р(В2),
…, Р(Bj). Вiзьмемо далi складний дослiд аb, який полягає в тому, що
водночас здiйснюються дослiди а i b. Спробуємо обчислити середню власну
iнформацiю, що мiститься в якому-небуть результатi складного дослiду
(Ai, Bj) або, iншими словами, ентропiю дослiду ab. По визначенню
ентропiя складного дослiду рiвна

H(a,b) = -?Р(Ai,Bj) log P(Ai,Вj). (1. 26)

ij

З iншого боку, ентропiя першого дослiду a рiвна

H(a,b) = -?Р(Ai) log P(Ai) (1. 27)

i

Пiдставимо далi в (1. 27) Р(Ai), що входять в перший спiвмножник
кожного доданку в виглядi

P(Ai) = -?P(Ai,Вj) (1. 28).

j

Вiдзначимо, що вираз (1. 28) являє собою запис формули повної
iмовiрностi для подiї Ai, тобто формулу (1. 12). Пiсля подстановки
(1.28) в (1. 27) отримаємо

H(a) = -??Р(Ai,Bj) log P(Ai) (1.29)

i j

Аналогiчно ентропiя дослiду b може бути представлена в виглядi

H(b) = -??Р(Ai,Bj) log P(Вj) (1.30)

i j

Якщо a i b – незалежнi дослiди, то для кожної пари результатiв Ai i Bj

P (Ai,Bj) = P(Ai) P(Bj),

отже,

log Р(Аi,Вj)=log Р(Ai) + log Р(Bj). (1.31)

Пiдставляючи далi (1. 31) в (1. 26), отримаємо

H(a,b)= – ??Р(Ai,Bj) log P(Ai) – ??Р(Ai,Bj) log P(Вj)

i j i j

Або, маючи на увазi (1. 29) i (1. 30),

H (ab) =H (а) + H (b). (1. 32)

Таким чином, при незалежних дослiдах ентропiя складного дослiду рiвна
сумi ентропiй кожного дослiду.

В бiльш загальному випадку, коли дослiди залежнi, iмовiрнiсть пари
результатів Ai, Bj може бути представлена в виглядi

Р (Аi, Вj) =Р(Аi) Р(Вj). (1. 33)

Вiдповiдно

log Р (Аi,Вj) = log Р(Ai) + logPAi(Bj). (1. 33′)

Тут PAi(Bj) означає умовну iмовiрнiсть результата Вj, якщо вiдомо, що
дослiд а закiнчився результатом Ai. Підставляючи (1. 33′) в (1. 20),
отримаємо

H(a,b) = -??Р(Ai,Bj) log P(Ai) – ??Р(Ai,Bj) log PAi(Вj) (1.34)

i j i j

Перша сума в виразi (1.34) являє собою (1.29) або ентропiю дослiду а.
Другу суму в (1.34) називають умовною ентропiєю дослiду b, припускаючи,
що який-небуть результат дослiду а мав мiсце. Цю ентропiю дослiду b за
умови дослiду а позначимо Ha(b). Тодi ентропiя складного дослiду, тобто
(1. 34), може бути записана

H (а, b)=H (a) + Ha(b). (1. 35)

По визначенню умовна ентропiя являє собою вираз

(1.36)

або, маючи на увазi (1. 33),

(1.37)

i j

Внутрiшня сума в виразi (1. 37), очевидно, являє собою ентропiю дослiду
b за умови, що дослiд a закiнчився конкретним результатом Ai. Справдi ця
внутрiшня сума нiчим не вiдрiзняється вiд виразу (1.19), за винятком
того, що замiсть iмовiрностей Р(Bj) тут стоять iмовiрностi результатiв
Bj при умовi, що був конкретний результат Ai. Цю умовну ентропiю дослiду
b при конкретному результатi дослiду а позначимо через HAi(b)

НАi(b) = – ?РAi(Bj) log PAi(Вj) (1.38)

j

При цьому вираз (1. 37), тобто умовна ентропiя дослiду b при дослiдi a,
може бути представлено як усереднення виразу (1. 38) по всiм результатам
дослiду а, тобто по всiм Аi

Нa(b) = – ?Р(Aj)HAi(Вj) (1.39)

i

Таким чином, умовна ентропiя дослiду b при дослiдi а являє собою
середню власну iнформацiю, що полягає в результатi дослiду b в
середньому при будь-якому результатi дослiду а.

Розглянемо властивостi умовної ентропiї.

1. Якщо дослiди a i b незалежнi, те умовна ентропiя рiвна безумовнiй

Ha(b) = H (b). (1.40)

Властивiсть (1.40) безпосередньо слiдує з порiвняння формул (1.32) i
(1.35), виведених вiдповiдно для випадкiв незалежних i залежних
дослiдiв.

2. Якщо результати першого дослiду, скажемо дослiду а, повнiстю
визначають результати iншого дослiду b (тобто дослiд а визначає дослiд
b), то умовна ентропiя рiвна нулю

Ha (b) = 0. (1.41)

Дiйсно, бо при цьому всi РAi(Bj) рiвнi або одиницi або нулю, в
вiдповiдностi з (1.38) величина HAi(b) рiвна нулю для всiх результатiв
Аi дослiду а. НAi(b)=0, тому вираз (1. 39) перетворюється в нуль.

3. Умовна ентропiя завжди менша або рiвна безумовної ентропiї, тобто

Ha(b) ??H (b). (1.42)

Знак рiвностi має мiсце при незалежностi дослiду а i b (див. властивiсть
1).

Для доказу спiввiдношення (1. 42) утворимо рiзницю

Ha(b)???H (b) = -??Р(Ai,Bj) log PAi(Вj) -(- ??Р(Ai,Bj) log P(Вj)) =
(1.43)

i j i j

= – ??Р(Ai,Bj) log (P(Вj)/PAi(Вj))

i j

Застосуємо до виразу (1.43) властивiсть логарифмiчної функцiї (1. 23),
поклавши тут w = Р(Bj)/PAi(Bj). Тодi

Ha(b)???H (b) ? log e ??Р(Ai,Bj)(P(Вj)/PAi(Вj) – 1)=0

i j

Дiйсно, права частина цiєї нерiвностi легко може бути записана як

log e [?Р(Ai)?Р(Bj) – 1] =0

i j

що тотожно рiвна нулю. Отже, Ha(b) – H (b) ??0, тобто доведена
нерiвнiсть (1.42). Знак рiвностi має мiсце при w=0, тобто при
P(Bj)/PAi(Bj) =1 для будь-яких Аi i Bj, або тодi, коли дослiди а i b
незалежнi.

Ми отримали результат, що умовна ентропiя дослiду b, якщо проведений
дослiд а, завжди менша або рiвна ентропiї дослiду b. Однак умовна
ентропiя дослiду b при конкретному результатi дослiду а, HAi(b) може
бути i меншою i бiльшою ентропiї дослiду b, Н(b). Цей факт можна
пояснити слiдуючим чином. Для одних результатiв Аi має мiсце HAi(b) <
H(b), для iнших, навпаки, HAi(b) буде бiльше H(b). Але в середньому в
сенсi формули (1. 39) ентропiя Hа(b) буде завжди менша або рiвна
ентропiї H (b).

Пояснимо сказане прикладом.

Нехай хворий страждає яким-небуть одним з трьох захворювань B1, B2, B3.
При цьому iмовiрнiсть того, що вiн страждає першим захворюванням, рiвна
Р(B1)=0.98, а iмовiрностi iнших захворювань вiдповiдно рiвнi Р(B2)
=P(B3) =0,01. Подальше дослiдження хворого a може мати два результата А1
i A2, причому результат А1 виключає захворювання B1, а результат A2
повнiстю пiдтверджує наявнiсть захворювання B1 i, отже, виключає
захворювання B2 i В3. Обчислимо ентропiю (невизначенiсть) ситуацiї до
проведення дослiдження a. Тодi

H(b)= – [P(B1) log P(B1) + P(B2) log P(B2) + P(B3) log P(B3)] =

= – [0,98 log0,98 + 0,01 log 0,01 + 0,01 log 0,01] = 0,16 бiт.

Вiдзначимо, що Р(A2) =0, 98, а Р(A1) = 0, 02, бо поява цих результатов
еквiвалентна подiям B1 i notВ1. Крiм того, очевидно, що PA1(B1) = 0,
PA1(B2)=PA1(B3) = 1/2, бо результат А1 виключає захворювання B1 i при
цьому залишаються два рiвноiмовiрних захворювання: В2 i B3. З iншого
боку, PA2(B1)=1 i PA2(B2) = PA2(B3) = 0. Обчислимо тепер ентропiю
(невизначенiсть) ситуацiї при конкретних результатах дослiдження a

НА1(b)= – [PA1(B1) log PA1(B1)+РА1(B2) log PA1(B2)+РA1(B3) log PA1(B3)]
=

= 0 + 1/2log2 + 1/2log2= 1 бiт,

НА2(b)= – [PA2(B1) log PA2(B1)+PA2(B2) log PA2(B2)+PA2(B3) log PA2(B3)]
=

=0 + 0 + 0 = 0.

Таким чином, ми бачимо, що результат А1 збiльшує ентропiю
(невизначенiсть) ситуацiї, а результат А2 зменшує. Цей факт має просте
фiзичне обгрунтування. Справдi, до проведення дослiдження a, розподiл
iмовiрностей захворювань був таким, що ми могли бути майже впевненi в
тому, що хворий страждає захворюванням В1, i в цьому сенсi
невизначенiсть ситуацiї була надто невелика (0, 16 бiт).

Однак, якщо в результатi дослiдження a з’являється результат A1 (що в
загалi-то малоймовiрно, але можливо), то в цьому випадку виявиться, що
хворий може мати яке-небуть одне з двох рiвноможливих захворювань B2 або
B3. В цьому випадку невизначенiсть ситуацiї виявиться вже значно бiльшою
(1 бiт). Але якщо в результатi дослiду a виникне результат А2 (що
вiдбувається в переважнiй бiльшостi випадкiв, в середньому в 98 випадках
з 100), та це твердо вкаже на наявнiсть у хворого захворювання В1, i,
отже жодної невизначенностi бiльше не буде (HA2(b)=0). Середня ж
ентропiя ситуацiї b за умови проведення iспиту а буде все-таки менша,
нiж Н(b)

Ha(b) = Р(А1)НA1(b)+Р(А2)НA2(b)=0, 02·1+0, 98·0=0, 02 бiт,

тобто

Ha(b) < H(b). 4. Оскiльки всяка ентропiя додатня, то вираз (1. 38) iстотно додатнiй, а отже, додатня i (1. 39). Отже, Ha(b) ? 0. (1.44) Об’єднуючи (1. 42) i (1. 44), отримаємо 0 ? Ha(b) ? H (b). (1.45) 5. В якостi п’ятої властивостi умовної ентропiї виведемо тотожнiсть Н(а) + Ha(b) = H (b) + Hb(a). (1.46) Вираз (1.46) безпосередньо слiдує з того факту, що складний дослiд ab нiчим нe вiдрiзняється вiд дослiду ba. Отже, H(аb) = H(ba) або H(a) + Ha(b) = H(b) + Hb(a). Розглянемо тепер питання про середню iнформацiю, що мiститься в одному дослiдi вiдносно iншого, або, iнакше кажучи, про середню вiдносну iнформацiю. Нехай невизначенiсть, зв’язана з деяким дослiдом b, виражається ентропiєю H(b). Здiйснення деякого iншого дослiду а зменшує невизначенiсть дослiду b. Це виражається в тому, що умовна ентропiя ситуацiї b пiсля проведення дослiду a стає меншою, нiж ентропiя ситуацiї b, тобто Ha(b) ? H(b). Різниця H(b) – Ha(b) являє собою зменшення невизначеностi дослiду b або, iншими словами, зменшення середньої власної iнформацiї в дослiдi b. Це зменшення власної iнформацiї в дослiдi b прeдcтавляє собою ту кiлькiсть iнформацiї, що несе дослiд a вiдносно дослiду b. В вiдповiдностi з цим середньою iнформацiєю одного дослiду вiдносно iншого називають вираз I(ab) = H(b) – Ha(b). (1.47) Враховуючи вираз (1.46), можемо записати H(b) – Ha(b) = H(a) – Hb(a) (1. 48) або I(ab) = I(ba) (1. 49) Таким чином, середня iнформацiя, що полягає в одному дослiдi вiдносно iншого, рiвна середнiй iнформацiї, укладеній в iншому дослiдi вiдносно першого. Оскiльки умовна ентропiя – величина iстотно додатня, то з (1. 47) i (1. 48) слiдує, що I(ab) ? H (a), I (ab) ? H (b). (1. 50) Нерівність (1. 50) виражае той факт, що середня iнформацiя, що мiститься в одному дослiдi вiдносно iншого, менша, нiж iнформацiя, укладена в середньому в кожному результатi цього дослiду вiдносно самого себе. Вiдноcна iнформацiя, що мiститься в конкретному результатi дослiду a, тобто в Аi, вiдносно всiх результатів дослiду b (в середньому) в вiдповiдностi з визначенням (1. 47), рiвна I (Aib) = H (b) – HAi(b). (1.51) Вона може бути i додатньою i вiдємною, оскiльки НАi(b) може бути i менше, i бiльше Н(b). В протилежнiсть цьому iнформацiя I(ab) завжди додатня, оскiльки На(b) завжди менше або рiвне H(b). Якщо же нас цiкавить iнформацiя, що мiститься в конкретному результаті дослiду ab (тобто в Ai) вiдносно конкретного результату дослiду b (тобто Bj), то в вирзi (1.51) слiд опустити усереднення по результатам Bj. Тодi отримаємо I(Аi, Вj) = – log Р(Bj) – (- log PAi(Bj)) = log (PAi(Bj)/P(Bj)), тобто вираз (1. 17). 1.2.4 Надлишковість Маємо деяку систему дослiдів a1, a2, …, am. Власна середня кiлькiсть iнформацiї на один результат кожного окремого дослiду рiвна його ентропiї I(a1) = Н(a1), I(a2) = Н(a2), . . . . . . . . . . . . . I(am) = Н(am), Власна середня кiлькiсть iнформацiї на один результат складного дослiду, являючого собою сукупнiсть дослiдiв a1, …, am, рiвна ентропiї складного дослiду I(a1, …, am) = H(a1, …, am). Якщо дослiди a1, …, am незалежнi, то в вiдповiдностi з (1. 32) H (а1, …, am) = H(a1) + H(a2) + … + H(am) або I (a1, …, am) = ?I(ai) (1.52) i Однак, якщо дослiди a1, …, am залежнi, то в вiдповiдностi з (1. 32), (1. 35) i (1.42) H(а1, …, am) ? H(a1) + H(a2) + … + H(am) або I (а1, …, am) ? I(a1) + I(a2) + … + I(am) (1.53) З (1. 52) i (1.53) слiдує, що з системи незалежних дослiдiв(випробувань) можна отримати бiльше iнформацiї, нiж з системи залежних. I навпаки, для отримання тiєї же iнформацiї в випадку незалежностi можна обiйтися меншою кiлькiстю випробувань. Це важливо мати на увазi при розробцi бiльш ощадливої системи iспитiв. Отже, в випадку залежних дослiдiв для отримання тiєї ж кiлькостi iнформацiї, ми повиннi проводити бiльшу кiлькiсть iспитiв, нiж це мiнiмально необхiдно, тобто вводити деяку надлишковiсть в iспитах. Для кiлькiсної оцiнки цiєї надлишковостi вводиться коєфiцiент надлишковостi, що виражає собою вiдносне зменшення кiлькостi одержуваної iнформацiї внаслiдок залежностi мiж дослiдом (1. 54) Поняття надлишковостi можна розповсюдити i на процес кодування i вiдповiдно прийти до подання надлишковостi коду. Припустимо, що для передачi деякої системи повiдомлень ми використаємо кодовi слова довжиною в n символiв, маючи в своєму розпорядженнi код з L рiзноманiтними символами (L – алфавiт коду). Якщо поява того або iншого символу на даному фiксованому мiсцi (в даному розрядi) кодового слова рiвноможлива, то кiлькiсть iнформацiї, що полягає в появi деякого символу на цьому фiксованому мiсцi, рiвна I (ai) = log L. [див (1.21)]. В той же час, якщо символи в кодовому словi незалежнi, тобто iмовiрнiсть появи даного символу не залежить вiд того, якi символи мiстяться в iнших розрядах кодового слова, то кiлькiсть iнформацiї, що мiститься в системi символiв (тобто в кодовому словi в цiлому), рiвна n ? I(ai) = n log L (1. 55) i=1 Вираз (1. 55) являє собою максимальну власну кiлькiсть iнформацiї, що може мiститися в кодовому словi довжиною в n символiв при алфавiтi L. Однак, якщо код мiстить обмеження, що полягає, наприклад, в неможливостi деяких комбiнацiй символiв (детермiнiстськi обмеження) або в тому, що iмовiрнiсть появи якого-небуть символа залежить вiд того, якi символи є в iнших розрядах кодового слова (ймовiрнiснi обмеження), то кiлькiсть iнформацiї, що мiститься в середньому в кожному кодовому словi, буде менша (1. 55). Цю кiлькiсть iнформацiї позначимо I(a1, …, an). Такий код буде володiти надлишковістю, рiвною в вiдповiдностi з (1.54). (1. 56) Тут сенс надлишковостi полягає в тому, що для передачi тiєї ж кiлькостi iнформацiї ми змушенi користуватися бiльш довгими кодовими словами, нiж це необхiдно. Наведемо приклад. Розглянемо двiйково-десятковий код, що часто використовується для подання кiлькiсних величi. 0-0000 1-0001 2-0010 3-0011 4-0100 5-0101 6-0110 7-0111 8-1000 9-1001 В цьому кодi кожний розряд десяткового числа представляється 4 двiйковими розрядами. В даному кодi можливi 10 рiзноманiтних повiдомлень, i якщо всi вони рiвноiмовiрнi (оптимальний випадок в сенсi максимума iнформацiї), то кiлькiсть iнформацiї на повiдомлення буде рiвно I(a1, …, a4) = log 10. А коефiцiент надлишковостi в вiдповiдностi з (1. 50) рiвний оскiльки тут n=4 i L=2. Отримана в цьому прикладi надлишковiсть двiйково-десяткового коду з’являється внаслiдок того, що ряд комбiнацiй в цьому кодi недопустимі. А саме, тут не мають сенсу наступнi комбiнацiї: 1010, 1011, 1100, 1101, 1111. До цих пiр ми розглядали надлишковість як небажане явище, що приводить або до необхiдностi ставити бiльше число дослiдiв, нiж це мiнiмально необхiдно, або в випадку кодування повiдомлень користуватися кодами бiльшої довжини. Однак надлишковість має позитивну сторону, так як дозволяє одержувати бiльшу надiйнiсть результатiв (дублювання дослiду), або, в випадку кодування, спецiальний ввiд надлишковостi дозволяє виявляти й виправляти помилки, що виникають в процесi передачi коду по каналу зв’язку. 1.2.5 Цiннiсть iнформацiї До цих пiр, коли ми говорили про iнформацiю, про її кiлькiсну мiру, ми мали на увазi тiльки свободу вибору, зв’язану з тим або iншим повiдомленням (фактом) або з тiєї чи iншою системою повiдомлень (дослiдiв); iншими словами, нас цiкавила тiльки статистична сукупнiсть, зв’язана з даним повiдомленням. При цьому сам змiст повiдомлення нiде не знаходив вiдбиття, за винятком поняття вiдносної iнформацiї, де вiн був важливим як деякий чинник, що змiнить статистичну сукупнiсть, зв’язану з iншим повiдомленням. Однак змiст повiдомлення в сенсi його цiнностi для споживача досi знаходився поза полем зору. Дiйсно, як вказано вище, повiдомлення про те, що в двухкаскадному пiдсилювачi, що зiпсувався, деякої системи управлiння зiпсувався саме перший каскад, мiстить стiльки ж iнформацiї, скiльки i повiдомлення про те, що дружина вашого товариша народила хлопчика, а саме I = -log1/2=1 бiт. Бо i в тому i в iншому випадку має мiсце свобода вибору з двох рiноможливих подiй. Означена обставина має i позитивне i негативне значення. Негативне – наче очевидно. Справдi, для рiзних споживачiв цi два повiдомлення далеко не однаково важливi. Для батька дитини друге повiдомлення незрiвнянно важливiше першого, а для людини, обслуговуючої радіолокацийну станцiю, якраз навпаки. Позитивна властивiсть згаданого факту полягає в тому, що для каналу зв’язку цi два повiдомлення справдi рiвнозначнi, бо їх можна передавати за допомогою одного i того ж однорозрядного двiйкового коду: 0 – при одному результатi, а 1 – при iншому. Отже, канал зв’язку, придатний для передачi повiдомлення першого типу, буде однаково хороший i для другого (в сенсi швидкостi передачi iнформацiї, можливостi виправлення помилок i т. д.) тому, що в обох повiдомленнях ми маємо дiло з однаковою свободою вибору. В цьому величезне значення теорiї iнформацiї, бо вона дозволяє будувати гарнi i надiйнi системи для передачi iнформацiї незалежно вiд конкретного змiсту повiдомлень. Однак в рамках теорiї iнформацiї не зовсiм безнадiйний стан i з проблемою визначення цiнностi конкретних повiдомлень. Бiльш того, в цьому вiдношеннi можна скористатися викладеним математичним апаратом. Для цього визначимо спочатку кiлькiсно, що таке цiннiсть iнформацiї, цiннiсть повiдомлення. Припустимо, що кожна людина на даному вiдрiзку часу здiйснює яку-небуть цiлеспрямовану дiяльнiсть, що може мати в якостi результату деяку множину результатiв Аj. Наприклад, якщо лiкар в даний момент займається встановленням дiагнозу, то можна сказати, що ця дiяльнiсть закiнчиться трьома результатами: А1 – буде поставлений правильний дiагноз, A2 – дiагноз не буде поставлений, А3 – дiагноз буде поставлений невiрно. Кожний з цих результатiв до отримання нової iнформацiї, нового повiдомлення володiє деякою апрiорною iмовiрнiстю Р(Аj). Ми можемо вважати, що отримане повiдомлення має яку-небуть цiннiсть в даний момент для цiєї людини, для цього споживача, якщо воно змiнює апрiорну iмовiрнiсть результату його дiяльностi, i не має цiнностi, якщо воно не змiнює цiєї iмовiрностi. Наприклад, для лiкаря, що ставить дiагноз, повiдомлення про деякий результат дослiдження даного хворого має значну цiннiсть i зовсiм цiнностi не має повiдомлення про те, що вийшов з ладу пiдсилювач в системi управлiння, бо останнє нiяк не змiнює iмовiрностi результату його дiяльностi. Тодi пiд цiннiстю деякого повiдомлення Si по вiдношенню до певного результату дiяльностi Aj будемо розумiти по аналогiї з (1.17) . (1.57) Iншими словами, цiннiсть даного повiдомлення по вiдношенню до даного результату дiяльностi, визначається як логарифм вiдносної змiни iмовiрностi деякого результату дiяльностi. Аналогiчно можна ввести поняття цiнностi повiдомлення Sj по вiдношенню до деякої дiяльностi a взагалi, що мiстить ряд результатiв Aj. Тут поняття цiнностi повiдомлення буде мати характер середньої цiнностi для всiх результатів даного виду дiяльностi C(Si, a) =H(a) – Hsi(a). (1. 58) Ентропiя H(а) не зв’язана з деяким дослiдом, а являє собою невизначенiсть в результатi дiяльностi даного споживача, що через iмовiрностi результатiв визначається за допомогою формули (1. 19). Нарештi, можна ввести поняття середньої цiнностi системи повiдомлень S(S1,S2, …, Si) по вiдношенню до даної дiяльностi споживача a(a1, a2, …, aj) C (S, а) =H(а) – Hs(a). (1.59) 1.2.6 Експоненціальний закон збiльшення числа повiдомленнь Всяку iнформацiю ми передаємо вiд одного джерела до iншого за допомогою певної системи символiв – кодiв, що складається з обмеженого числа знакiв – алфавiту. Наприклад, всi слова i речення в росiйськiй мовi можна передати за допомогою 32 знакiв. Тут алфавiт мiстить L=32 символа. В двiйковiй системi числення алфавiт мiстить L=2 символiв (0 i 1), в десятковiй L=10 i т. д. Доведемо тепер, що якщо код не мiстить обмежень, те послiдовнiсть з n символiв припускає можливiсть скласти N=Ln (1.60) рiзноманiтних повiдомлень. В цьому i заключаеться експоненциальний закон збiльшення числа повiдомлень з збiльшенням довжини повiдомлення n. Покажемо справедливiсть виразу (1. 60) за допомогою методу математичної iндукцiї. Для цього достатньо довести два твердження: а) якщо вираз (1.60) вiрний для будь-якого n (n – цiле, додатне число), те вiн вiрний i для n+1; б) вираз (1. 60) справедливий для n=1. Очевидно, що якщо твердження (а) i (б) справедливi, те вираз (1.60) вiрний для будь-якого n. Почнемо з твердження (б). Якщо n=1, тобто наше повiдомлення складається тiльки з одного символу, то в якостi цього символу ми можемо взяти будь-який з L, тобто число рiзноманiтних повiдомлень буде N=L. Це число i дасть формула (1. 60) при n=1. Перейдемо до доведення твердження (а). Нехай ми маємо послiдовнiсть довжиною в n символiв. Тодi по припущенню кiлькiсть рiзноманiтних повiдомлень, що можна здiйснити за допомогою такої послiдовностi, рiвна Ln. Додамо до цiєї послiдовностi ще один символ. Тодi, підставляючи на це нове мiсце будь-який з L символiв, отримаємо з кожного старого повiдомлення L нових повiдомлень. Всього кiлькiсть нових повiдомлень буде рiвна Nn+1 = Ln · L = Ln+1 , тобто ми довели, що якщо вираз (1.60) справедливий для n, то вiн справедливий i для n+1. Формулу (1. 60) можна видозмiнити слiдуючим чином. Нехай час передачi кожного символа рiвно t сек (будемо вважати, що тривалiсть передачi всiх символiв однакова). Тодi тривалiсть передачi повiдомлень з n символiв буде рiвна Т = nt сек. (1.61) Виключаючи n з формул (1.61) i (1.60), отримаємо N = Ln = LT/t = LbT, (1. 62) де b=1/t (символ/сек) являє собою швидкiсть передачi символiв по каналу. Таким чином, можливе число рiзноманiтних повiдомлень тривалостi Т росте зi збiльшенням T по експоненцiальному закону, що в функцiї часу справедливо i тодi, коли тривалiсть передачi окремих символiв неоднакова (але T >> ti). При цьому вiн набуває вигляду

N(T)=AwT, (1. 63)

де А i w залежать вiд L i довжини символiв. Так, w визначається як
найбiльший дiйсний корень рiвняння

(1. 64)

де t1, t2, …, tL – довжини символiв алфавiту.

Експоненціальнiй закон збiльшення числа повiдомлень справедливий i
тодi, коли в кодi є детермiнiстськi або ймовiрноснi обмеження кiнцевої
тривалостi, але коли ми маємо дiло з так званими ергодичними
повiдомленнями, де довжина повiдомлення значно бiльша, нiж довжина
обмежень (пiд кiнцевою довжиною обмежень ми розумiємо, що обмеження
розповсюджується тiльки на кiнцеве число наступних символiв).

Проiлюструємо сказане прикладом. Нехай за допомогою двiйкового
цифрового коду потрiбно передати ординати електрокардiограмми з точнiстю
до 1%. Яку довжину (скiльки розрядiв) двiйкового коду потрiбно взяти для
цiєї мети? Оскiльки задана точнiсть 1%, то кiлькiсть рiзноманiтних
повiдомлень (рiзноманiтних числових значень електрокардiограмми) буде
N=100; L=2. Отже, n визначається з формули 100=2n, або найближче бiльше
цiле n=7. Отже, для цифровой передачi електрокардiограмми зi згаданою
точнiстю достатньо скористатися семирозрядним двiйковим кодом.

КОДИ З ВИЯВЛЕННЯМ ТА ВИПРАВЛЕННЯМ ПОМИЛОК

Кодування інформації

Кодуванням називається процес встановлення певної вiдповiдностi мiж
повiдомленнями i тiєю системою символiв, за допомогою яких цi
повiдомлення передаються. Сама система символiв називається кодом.

Основнi цiлi кодування наступнi.

1. Надання повiдомленням максимально короткої (стислої) форми з метою
збiльшення пропускної спроможностi каналу, зоокрема для кращого
використання пам’ятi в математичних машинах.

2. Надання повiдомленням форми, зручної для подання їх за допомогою
електричних або механiчних сигналiв.

3. Максимальне спрощення логiчних i обчислювальних операцiй над
повiдомленнями. Наприклад, якщо кiлькiснi повiдомлення представленi
десятковим кодом (десяткова система числення), то для виконання операцiї
множення необхiдно було б реалiзувати фiзично в пам’ятi машини таблицю
множення. Якщо ж цi повiдомлення кодувати двiйковим кодом (двiйкова
система числення), то оскiльки всi символи коду – одиницi або нулi, то
потреба в таблицi множення пропадає; множення на нуль дасть нуль, а
множення на одиницю зводиться до повторення числа.

4. Максимальна помiхостійкiсть лiнiї зв’язку i приладiв передачi i
обробки iнформацiї.

Звичайно, створити код, що задовольняв би всiм перерахованим умовам,
практичнi неможливо. Тому в залежностi вiд головних вимог, що
накладаються системою або частиною системи, вибирають код, що краще
всього задовольняє якiйсь з цих умов. При цьому нерiдко для однiєї
частини системи використовують одну систему кодування, а для iншої –
iншу. Стикуючи їх за допомогою приладiв, що переводять один код в iнший.

Так, наприклад, для лiнiї передачi iнформацiї, де важлива максимальна
швидкiсть передачi повiдомлень, тобто максимальне використання
пропускної спроможностi каналу, код слiд вибирати по першiй умовi. В
цьому випадку може виявитися найбiльш зручним метод кодування Фано.
Однак такий код являє собою код змiнної довжини, внаслiдок чого вiн
незручний для виконання логічних i обчислювальних операцiй. Тому для
обчислювальних приладiв системи бажаний код, що задовольняє третiй
умовi, i т. д.

Найбiльш часто ми зустрiчаємось з проблемою кодування, коли маємо дiло
з кiлькiсними повiдомленнями. Всяка система числення в принципi є певним
кодом. Наприклад, в десятковiй системi число 123 представляється в
виглядi: 1·102+ 2·101+ 3·100, тобто в виглядi суми мiр десятки. При
цьому кодом числа є коефiцiенти при цих мiрах, тобто в даному випадку
123. Алфавiт такого коду складається з 10 символiв 0, 1, 2, 3, …, 9,
тобто L=10. Аналогiчно в двiйковiй системi числення, числа
представляються в виглядi суми мiр двiйки. Наприклад, число 14
представляється в виглядi 1·23 + 1·22 + 1·21 + 0·20 або 1110. Тут кодом
є коефiцiенти при вiдповiдних мiрах двiйки, i, отже алфавiт коду мiстить
два символи – 0 i 1, тобто L= 2.

Декодування – процес, зворотний кодуванню. Вiн полягає в переходi вiд
системи символiв до повiдомлень на звичайнiй мовi. Отже, процес
декодування використовує ту ж систему вiдповiдностi, але в зворотньому
напрямку. В принципi, код – це мова даної iнформацiйної системи. Тому
кодування i декодування – це перехiд з однiєї мови на iншу.

Якщо в якостi сигналу, що передає iнформацiю, використовується
безперервний сигнал, та вiдповiднiсть мiж повiдомленням i сигналом
звичайно представляється за допомогою масштабного множника

х(t) =me (t). (1.86)

Тут x(t) – деяка кiлькiсна величина (повiдомлення), e(t) – безперервний
фiзичний сигнал (наприклад, електрична напруга), m -масштабний множник.
Безперервнi сигнали використовуються головним чином для передачi
кiлькiсної iнформацiї, наприклад математичних змiнних в обчислювальних
машинах безперервної дiї.

Навпаки, при дискретних сигналах навiть при передачi кiлькiсної
iнформацiї використовуються коди, i в принципi окремi сигнали передають
символи кодiв. Оскiльки кiлькiсть рiзноманiтних символiв обмежена
(алфавiт коду), то достатньо мати всього декiлька дискретнiх рiвнiв
сигналу для передачi будь-якого повiдомлення. Останнє дозволяє iстотно
збiльшити точнiсть i помiхостiйкiсть систем передачi i обробки
iнформацiї, бо тiльки дуже сильнi перешкоди можуть викривити сигнал ,що
передаеться, настiльки, що на приймальному кiнцi даний рiвень сигналу,
котрий представляє даний символ, може бути прийнятий за iнший рiвень
сигналу котрий представляє iнший символ. Саме тому цифрова електронна
математична машина, де iнформацiя представлена дискретним кодом (тому
вона i називається цифровою), значно точнiша, нiж математична машина
безперервної дiї (аналогова).

Вибiр того або iншого коду визначається головною метою, яку ми
переслiдуємо при кодуваннi. Однак незалежно вiд цього будь-який код
повинен задовольняти наступнiй основнiй умовi: даний код може служити
мовою деякої iнформацiйної системи в тому i тiльки в тому випадку, якщо
свобода вибору в кодi (його ентропiя) рiвна або бiльша свободи вибору в
iнформацiї (в системi повiдомлень). Справдi, очевидно, необхiдна умова
вибору коду полягає в тому, щоб число допустимих комбiнацiй коду Nk
було бiльше або рiвне числу рiзноманiтних повiдомлень Nc, тобто

Nk ??Nc. (1.87)

Виберемо код постiйної довжини, алфавiт якого складається з L символiв
i число позицiй (довжина кодового слова) рiвно n. За допомогою такого
коду можна утворити Ln рiзноманiтних комбiнацiй (за вiдсутностi в кодi
обмежень)

Nk = Ln. (1.88)

Пiдставляючи (1.88) в нерiвнiсть (1.87), отримаємо

Ln ??Nc

або

nlogL ? logNc (1.89)

звiдки

n ? log Nc/log L (1.90)

Умова (1.90) – це умова вибору мiнiмального коду постiйної довжини для
даної системи повiдомлень. Тут n – найближче бiльше цiле число, причому
якщо має мiсце знак >, то код буде надлишковим.

Так як всi Ln комбiнацiї рiвноможливi, свобода вибору коду рiвна

Hk = logNk = n logL. (1.91)

З iншого боку, максимальна свобода вибору iнформацiї буде при
рiвноможливих повiдомленнях, i в цьому випадку вона рiвна

Hc= logNc. (1.92)

Порiвнюючи (1.91), (1.92) з (1.89), отримаємо, що умова (1. 89)
рівносильна

Hk ? Hс (1. 93)

Таким чином, свобода вибору в кодi повинна бути бiльша або рiвна
свободi вибору в системi повiдомлень. Якщо ж iмовiрностi рiзноманiтних
повiдомлень неоднаковi, то необхiдна рiвнiсть в (1. 87) або (1. 89)
призведе до нерiвностi в (1.93) (так як log Nс>Hc), тобто в цих випадках
код постiйної довжини надлишковий. При нерiвноможливих повiдомленнях
отримати рiвнiсть водночас в (1. 87) i (1. 93), тобто отримати код,
оптимальний в сенсi мiнiмуму довжини повiдомлень, можна тiльки за
допомогою коду змiнної довжини .

1.3.2 Коди з виявленням i виправленням помилок

До цих пiр ми розглядали надлишковiсть як небажане явище, що приводиться
до надмiрного збiльшення коду. В цьому роздiлi ми покажемо, що в
багатьох випадках корисно спецiально вводити надлишковiсть з метою
збiльшення помiхостiйкостi системи, передбачаючи можливiсть вiдкриття i
виправлення помилок при передачi iнформацiї.

Найбiльш простим засобом виявлення на приймальному кiнцi можливої
помилки в повiдомленнях ,що передаються є так звана, перевiрка на
парнiсть. Припустимо, ми передаємо iнформацiю за допомогою двйкового
коду i припустимо, що група з n символiв може мiстити не бiльш однiєї
помилки. Для здiйснення перевiрки на кiнцi,що передає, розбиваємо кожне
повiдомлення на групи з m=n-1 символiв. До кожної групи дописуємо один
символ так, щоб сума цифр в отриманiй групi з n символiв була парною.
Наприклад, при n=6

сигнал Провiрочний сигнал що

символ передається

10110 1 101101

10111 0 101110

Це дозволяє на приймальному кiнцi вiдразу виявити одноразову помилку,
якщо прийнятий сигнал виявиться непарним. Для цього прийняте
повiдомлення дiлять на групи з n символiв i визначають парнiсть суми
цифр кожної групи. Пiсля перевiрки останнiй символ в кожнiй групi
вiдкидається.

Однак такий простий засiб не дозволяє з’ясувати, в якому саме мiсцi
нашого коду вiдбулася помилка. Крiм того, такий пiдхiд не дозволяє
виявити подвiйну помилку, бо помилковий сигнал залишиться парним.

В 1950 г. Р. Хеммiнг поклав початок дуже важливим роботам по створенню
кодiв, що виявляють i виправляють помилки, запропонований ним пiдхiд
полягає в додаваннi не одного, а декiлькох провiрочних символiв i
здiйсненнi декiлькох перевiрок на парнiсть в вiдповiдностi з виробленими
правилами.

Розглянемо основну iдею цього методу. Маємо сукупнiсть з n двiйкових
символiв i припускаємо, що в кодах довжиною n не зустрiчається бiльше
однiєї помилки. З n символiв кодового слова m символiв будемо
використовувати для передачi сигналу (повiдомлення), а iншi k символiв –
для перевiрки

n=m+ k. (1. 94)

За допомогою k провiрочних символiв можна скласти 2k рiзноманiтних
комбiнацiй (рiзноманiтних двiйкових чисел), кожна з котрих повинна
вказувати на один з наступних фактiв:

1) помилки немає; 2) помилка в першому символi; 3) помилка в другому
символi i т. д.; n+1)помилка в символi номер n. Всього одержується n+1
вказiвка. Звiдки слiдує умова

2k(n+1. (1.95)

Умова (1.95) дозволяє вибрати найменше число провiрочних символiв,
необхiдних для виявлення i виправлення одиничної помилки в кодi довжиною
n символiв. Таким чином, k – найменше цiле число, що задовольнить (1.
95). Сказане iлюструє таблиця, в якій найбiльше число символiв n може
бути перевiрене застосуванням вiд 1 до 5 проверочнiх символiв k.

Кількість перевірочних символів k Всього символів n Інформаційні символи

m =n-k

1 1 0

2 3 1

3 7 4

4 15 11

5 31 26

Спочатку розглянемо метод Хеммінга на прикладi третього випадку
таблицi, так званого коду ‘4 з 7’, де чотири двiйкових символа видiленi
для iнформацiї, а три – для перевiрки. Таким чином, наша мета полягає в
виявленнi i локалiзацiї помилок в припущеннi, що в групi з семи
двiйкових символiв нiколи не зустрiчається бiльше однiєї помилки. Для
цього складемо наступнi провiрочнi суми, в вiдповiдностi з якими на
кiнцi, що передає будемо заповнювати вмiст провiрочни розрядiв, а на
приймальному кiнцi перевiряти цi суми на парнiсть.

Нехай y1, y2, y3, y4 – вмiст m iнформацiйних розрядiв нашого сигналу (в
даному випадку m=4). Крiм того, с5, c6, c7 – вмiст k проверочнiх
розрядiв (в даному випадку k=3). Тодi провiрочнi суми мають вигляд:

Сума I: y1+ y2+ y3+ c5,

Сума II: y1+ y2+ y4+ c6, (1. 96)

Сума III: y1+ y3+ y4+ c7,

В залежностi вiд конкретного змiсту символiв y1, y2, y3, y4
встановлюється змiст символiв c5, c6, c7, так, щоб суми (1. 90) були
парними. На табл. 1 крестики вiдповiдають методу складання перевiрочнiх
сум.На приймальному кiнцi знов складаються всi суми (1.96). Якщо вони
парнi, то помилки немає. Якщо виявилася непарною одна з сум, то помилка
в провiрочному символi цiєї суми, бо всi iншi

Таблиця 1

Інформація

Перевірка

1 2 3 4 5 6 7

y1 y2 y3 y4 c5 c6 C7

X X X

X

Сума І

X X

X

X

Сума ІІ

X

X X

X Сума ІІІ

символи входять i в iншi суми, а вони парнi. Якщо двi суми непарнi, то
помилка в тому символi, що входить в обидвi цi суми, але нс входить в
третю. Нарештi, якщо всi суми непарнi, то помилка в тому символi, що
входить в всi цi суми. Як тiльки визначено, в якому символi помилка, її
виправлення не представляє складностi. Потрiбно замiсть даного символу
поставити протилежний (якщо стоїть 0, поставити 1, а якщо 1, поставити
0). Проiлюструємо сказане прикладом використання коду “4 з 7”.

Маємо повiдомлення, кодоване двiйковими символами.

0000100010100100.

Подiлимо його на групи по чотири символи в кожнiй

0000 1000 1010 0100.

На кiнцi ,кожної з чотиризначних груп доповнимо ще трьома символами
(c5, c6, c7), вiдповiдними перевiркам на парнiсть згiдно (1.96). Тодi
отримаємо

0000000 1000111 1010010 0100110.

В пiдсумку повiдомлення ,що передається буде мати вигляд
0000000100011110100100100110.

На приймальному кiнцi повiдомлення розбивається на групи по сiм знакiв,
здiйснюється перевiрка на парнiсть в вiдповiдностi з сумами (1.96), якщо
необхiдно виправляються помилки, а пiсля цього в кожнiй семизначнiй
групi усуваються три останнi знаки. Таким чином ми вiдновимо вхiдне
повiдомлення. Приклад коду ‘4 з 7′ пояснює загальний метод,
запропонований Хеммiнгом. Вiн полягає в наступному. Складаємо стiльки
перевiрочних сум, скiльки перевiрочних символiв встановлює нерiвнiсть
(1.95). Кожна перевiрочна сума мiстить тiльки один перевiрочний символ
ci, i кожний даний провiрочний символ зустрiчається в усiх сумах тiльки
один раз. Перший символ y1 (з m iнформацiйних) входить у всi суми,
кожний з наступних y2…yk+1 символiв входить в k-1 з k проверочнiх сум.
Пiсля цього, якщо m>k iншi yk+2… символiв входять в (k – 2)
провірочних сум. Так, можна розмiстити ще 1/2 k (k-1)

Таблиця 2.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

y1 Y2 y3 y4 y5 y6 y7 y8 y9 y10 y11 c12 c13 c14 c15

X X X X – X X X – – – X – – –

X X X – X X – – X X – – X – –

X X – X X – X – X – X – – X –

X – X X X – – X – X X – – – X

символiв з залишившихся m iнформацiйних i т. д. Цей метод утворення
провірочних сум наочно iлюструє приклад коду ’11 з 15’ (табл. 2).

вказiвок можливих комбiнацiй по двi помилки, тобто повинно мати мiсце

. (1.97)

вказiвок можливих комбiнацiй по три помилки, тобто

2k>= (n+1) + l/2n(n -1) + 1/3! n(n – 1), (1.98)

i т. д.

Таким чином, ми бачимо, що кiлькiсть провiрочнiх символiв дуже швидко
росте. Тому на практицi вигiднiше розбивати все повiдомлення на пiдгрупи
так, щоб в кожнiй підгруппi було по можливостi не бiльше однiєї помилки,
нiж мати дiло з довгим повiдомленням, припускаючи можливiсть кратної
помилки.

Викладенi iдеї можна дуже наочно проiлюструвати геометрично. Уявимо
собi, що для передачi можливих N повiдомлень ми користуємось n-розрядним
двiйковим кодом. Кожне n-розрядне двiйкове слово можна уявити точкою в
n-мiрному просторi, координати якого – значення символiв по кожному
розряду (0 або 1). Якщо n=3, то ми маємо звичайний тривимiрний простiр,
де означенi точки утворять вершини одиничного куба (рис. 7).

Домовимося називати вiдстанню dij мiж двома кодовiми словами (двома
вершинами куба) найменше число їхнiх ребер ,що роздiляють їх або, що те
ж саме, кiлькiсть порозряднiх не-збiгiв в цих двох словах. Наприклад,
вiдстань мiж двiйковими словами 101100 i 100110 рiвна dij =2. Якщо код
не володiє надлишковiстю, тобто N=2n, те кожному кодовому слову
вiдповiдає своє повiдомлення i мiнiмальний iнтервал при такому кодуваннi
dij min рiвний 1. Природньо, що такий код не може виявити помилку, бо
будь-яка помилка перекладає дане слово в iнше, вiдповiдне iншому
повiдомленню. Цю помилку не можна буде вiдрiзнити вiд iншого сигналу.
Якщо ж N<2n, тобто має мiсце надлишковiсть, те не всi вершини куба можна
взяти в якостi кодових слiв, вiдповiдних повiдомленням, а тiльки частину
з них. Тодi можна вибрати код, при якому dijmin=2, i виявити одну
помилку (але не виправити). Дiйсно, наявнiсть помилки призведе до того,
що помилкове слово буде стояти вiд iншого кодового слова на iнтервалi,
рiвному dij=1. А це для iстинних повiдомлень неможливо. Але подвiйну
помилку вже виявити не можна, бо вона переведе наше слово в iнше кодовое
слово, вiдповiдне iншому iстинному повiдомленню. Якщо вибрати код з
мiнiмальним iнтервалом dij min=3, то одинична помилка призведе до
отримання слова, що стоїть на вiдстанi dij=1 вiд вхiдного. Але вiд iнших
слiв коду, вiдповiдних iстинним повiдомленням, воно буде вiдстояти
мiнiмум на двi одиницi. Це дозволяє знайти викривлене слово (вхiдне),
тобто виправити помилку. Таким чином, код з dij min=3 дозволяє виправити
одиничну помилку i виявити подвiйну. В загальному випадку, якщо N << 2n
(бiльша надлишковiсть), то при мiнiмальнiй вiдстанi мiж словами, рiвнiй
dijmin = 2(m+1) (m – цiле, додатнє), можна побудувати код, що виправляє
v-кратну помилку (v= 1, 2,…, m) або що виявляє 2v-кратну.

2. Огляд найбільш вживаних

типів штрихових кодів

2.1 Загальний огляд

Як правило той або інший тип штрихкоду вибирають, виходячи з наступних
чинників:

Прикладний пакет підтримує тільки один тип коду;

Промислові стандарти диктують той або інший тип коду;

Тип коду вибирається виходячи з умови відповідності іншим системам

і/або обладнанню ,що використається;

Особисті вподобання керівника.

Дуже часто штрихкоди наносять так, як про це просить майбутній продавець
даного товару. В цьому випадку виробник, імпортер, або пакувальник при
нанесенні EAN-коду використає номер виробника. На тару може наноситися
або 13-символьний EAN-код, або 14-символьний ITF. Найбільший по розміру
EAN-код, що може бути нанесений, занадто малий і тому може загубитися на
великій тарі. Він також вимагає високої точності друку, що неможливо при
друкуванню на такому матеріалі, як наприклад, картонні коробки. ITF-код
може бути значно більшого розміру і для нього допустимі більші
відхилення ширини ліній і пробілів, що робить можливим прямий друк
навіть на низкоякісному субстраті. Кожному, хто використовує штрихове
кодування в роздрібній торгівлі, слід подумати про використання
EAN-кодів. Для торгівлі харчовими продуктами вони є узвичаєним
стандартом. Але оскільки багато організацій, що торгують харчовими
продуктами, продають зараз багато нехарчових, а продавці наполягають на
маркуванні їх за допомогою EAN, тому безліч інших видів продукції
доставляється зараз вже маркованими за допомогою EAN. Однак в торгівлі
взуттям і ювелірними виробами прийняте маркування за допомогою ITF.
Гнучкість цього коду відносно довжини робить його більш придатним, ніж
EAN з жорстко фіксованими розмірами. Контрольна цифра в ITF
необовязкова, але може використовуватися, з умовою, що прінтер і сканер
штрихкода працюють в одному режимі. CODE 39 – мабуть, найбільш
розповсюджений в неторгівельній сфері. Його обрали збройні сили і
автомобільна промисловість. Якщо вимагаються різноманітні довжини кодів,
а також використання літерних символів, найбільш зручним є CODE 39. В
поштовій справі знайшов своє примінення штрихкод типу POSTNet. Для
кодування великих об’ємів інформації на малій площі застосовують
двомірні штрихові коди, такі як PDF-417, DATAMATRIX та ін.

Нижче найвживаніша штрихкодова символіка розглядатиметься більш
докладно. Потрібно зазначити основні параметри якими характеризується
симоліка штрихових кодів:

Співвідношенням між широким і вузьким елементами – друкованим

відношенням

шириною вузького елементу (часто називають ширина модуля)

комбінаціями штрихів і пробілів для кодування знаків

кількістю знаків в символі

комбінаціями штрихів і пробілів для кодування старт/стоп знаків.

допусками при друці кожного елементу

контрольним розрядом (контрольною сумою)

В даній таблиці наведено основну характеристику найбільш вживаних
світових стандартів штрихових кодів.

Таблиця 3

№ Тип штрихкода Довжина Контрол. Розряд Допустимі символи

1 3 of 9 Різна – 0-9, A-Z, -.*/+% и пробіл

2 UPC-A 11 цифр + 0-9

3 UPC-E 6 цифр + 0-9

4 Interleaved 2 of 5 Різна – 0-9

5 Code 128 (A,B,C) Різна M-103 128 символів ASCII

6 EAN-13 12 цифр + 0-9

7 EAN-8 7 цифр + 0-9

8 Health Industry Bar Code (HIBC) Різна M-43 0-9, A-Z, -.$:/.   Повинен
починатися з “+”

9 Codabar Різна(Мін. 3 символа) – 0-9,-,.,$,:,/,+, і коди старт/стопа a,
b, c и d

10 Interleaved 2 of 5 without Bars Різна M-10 0-9

11 MSI Plessey Різна M-10 0-9, Якщо + останній символ, на місто символа
+ буде добавлена додаткова контрольна сумма MSI

12 Interleaved 2 of 5 (UPC CASE) 13 M-10 0-9

13 UPC 2 digit add 2 цифри + 0-9

14 UPC 5 digit add 5 цифр + 0-9

15 Code 93 Різна – 128 символів ASCII

16 Postnet Різна + 0-9

17 UCC/EAN Code   128 19 цифр + 0-9

18 UCC/EAN Code   128 K-MART   NON EDI 18 цифр + 0-9

19 UCC/EAN Code   128 Random Weight Різна,   принаймні 34 цифри + 0-9

20 Telepen Різна + 128 символів ASCII

21 UPS MaxiCode 84 + 0-9, A-Z

22 FIM 1 символ – A, B, C або D

23 PDF-417 Різна + Всі символи ASCII

2.2 Тип EAN-13, UPC та EAN-8

Цей код частіше інших зустрічається на упаковках імпортних продуктів
харчування в супермаркетах. EAN – абревіатура European Article Number
(європейський номер товару), а американський еквівалент UPC –
абревиатура від Universal Product Code (унивесальный код товару).Існують
2 типи штрихового коду EAN: EAN8, що кодується вісьмома цифрами і EAN13,
що кодуєтся тринадцятьма цифрами. Слово ‘цифра’, а не ‘символ’,
використовується навмисне, тому що EAN (і UPC) можуть містити тільки
цифри.

Штрихові коди UPC, на перший погляд, мають вигляд точнісінько такий, як
і коди EAN, але вони складаються тільки з дванадцяти (UPS-A) або шести
(UPS-E) цифр. EAN International – це добровільна некоммерційна і не
урядова міжнародна Асоціація, що складається з національних організацій
(в нинішній час 80 організацій в 89 країнах). EAN (European Article
Numbering) International управляє міжнародною багатогалузевою системою
товарної нумерації і стандартів штрихового кодування, що дозволить
ідентифікувати і передавати дані про товари, послуги, підприємства,
транспортні одиниці і адресні дані.

Розглянемо структуру штрихового коду типів ЕAN на прикладі EAN-13.

Перші 3 цифри називаються префіксом EAN і присвоюються EAN
International. Ними ідентифікуються національні організації. Национальні
організації товарної нумерації уповноважені EAN International
використовують систему EAN на національному або регіональному рівнях в
якості офіційних представників EAN. В окремо взятій країні

або регіоні може існувати тільки один представник EAN Intrernational.
Префікси 460-469 в коді EAN-13 присвоєні Росії. Префікс 482 присвоєно
ЮНІСКАН/EAN України. Префікс завжди є зісланням на національну
організацію. Так префікс 482 означає, що підприємство зареєстроване в
Українському відділенні EAN, а зовсім не те, що підприємство знаходиться
на території України. В національну організацію України може вступити
будь-яке підприємство, наприклад, розташоване на території Німеччини,
Казахстану, Росії і т. д., за умови, що воно має своє представництво в
Україні. При вступі в ЮНІСКАН/EAN України підприємству буде присвоєний
відповідний код, що починається префіксом 482. Аналогічно, наприклад,
префікс 50 означає, що підприємство зареєстроване в національній
організації Великобританії, а не те, що воно розміщене на англійській
території. (Префікси деяких національних організацій складаються з 2
цифр.) Наступні 9 цифр містять номер підприємства, що зареєструвалось
всередині національної організації, і номер товару. Структура 9 знаків,
що належать номеру підприємства і номеру товару, визначається
безпосередньо національною організацією, наприклад:

5 – підприємство/4 – товар,

6 – підприємство/3 – товар,

7 – підприємство/2 – товар і ін.

В нинішній час ЮНІСКАН/EAN України визначило наступну структуру: 4 цифри
– номер підприємства, 5 цифр – номер товару. Остання 13 цифра
називається контрольним розрядом. Вона призначена для перевірки
правильності считування коду EAN скануючим пристроєм. Прочитавши
графічне зображення штрихового коду за допомогою сканера і перетворивши
його в цифровий код, комп’ютер по спеціальному алгоритму обчислює
контрольний розряд і порівнює його із зісканованим з графічного
зображення. Збіг зісканованого і обчисленого контрольних розрядів
означає правильне считування штрихового коду. В цьому випадку на сканері
з’являється відповідний світловий/звуковий сигнал. Якщо код читається
погано, то одна або декілька цифр коду можуть бути при зчитуванні
викривлені. В цьому випадку сканер не дасть сигнал про правильне
зчитування. Аналогічно, якщо хто-небуть придумав свій код з довільних 13
цифр або, якщо контрольний розряд має довільне значення, те цей
штриховий код сканером зчитуватися не буде.

Розглянемо алгоритм знаходження контрольного числа(розряду) для коду
EAN13.

В процесі знаходження контрольного числа в коді EAN 13 використовуються
наступні значення:

МОДУЛЬ: 10

ВАГИ: 131313131313

СУМА: Добутків

Пояснимо це детальніше, розбивши весь процес знаходження контрольного
числа на кроки.

КРОК 1: Починаючи з крайнього праворуч розряду, виключаючи контрольний
розряд, скласти величини парних розрядів;

КРОК 2: Результат КРОКУ 1 помножити на 3;

КРОК 3: Скласти величини розрядів ,що залишалися;

КРОК 4: Скласти результати КРОКІВ 2 і 3;

КРОК 5: Значення контрольного розряду є найменшим числом, що в сумі з
величиною, отриманої в КРОЦІ 4, дасть число, кратне 10.

Приклад розрахунку контрольного розряду в коді EAN-13 =467622135746С

4 6 7 6 2 2 1 3 5 7 4 6 C

Крок 1: 6+6+2+3+7+6=30

Крок 2: 30(3=90

Крок 3: 4+7+2+1+5+4 =23

Крок 4: крок 2+ крок 3=113

Крок 5: С=120-113=7

Роз’яснення: наступне за 113 найближче кратне 10 число рівне 120. Тому
контрольний розряд в коді EAN-13 буде рівний: 120 – 113=7, а повний
номер EAN-13 буде наступним: 4676221357467.

Розглянемо особливості графічної побудови кодів типу EAN-13. Штрихові
коди цього типу повинні мати так-звані “тихі зони” з обох боків
штрихкоду. “Тихі зони” – незаповнені області, вільні від будь-якого
друку, звичайно їх ширина не повинна бути меншою десятикратної ширини
найменшого бруска штрихового коду.

Якщо уважно роздивитися штриховий код EAN-13, то можна побачити, що на
початку та в кінці, а також посередині штрихкоду є бруски довжина яких
більша ніж у інших. Ці бруски є контрольними і використовуються для
“регулювання” сканера. Перше число з 13-ти значного коду розташоване
зовні цих брусків, решта 12 поділена на дві групи й записані в середині
коду. Кожне число закодоване через сім брусків: чорний=1 та білий=0.

Штриховий код використовує три набори бітових рядів для представлення
чисел 0-9.

Таблиця 4.

№ Набір А Набір В
Набір С

0 0001101 13 0100111 39 1110010 114

1 0011001 25 0110011 51 1100110 102

2 0010011 19 0011011 27 1101100 108

3 0111101 61 0100001 33 1000010 66

4 0100011 35 0011101 29 1011100 92

5 0110001 49 0111001 57 1001110 78

6 0101111 47 0000101 05 1010000 80

7 0111011 59 0010001 17 1000100 68

8 0110111 55 0001001 09 1001000 72

9 0001011 11 0010111 23 1110100 116

Границі: 101

Центр: 01010

Для використання цієї таблиці необовязково знати її всю. Набори В та С
можна утворити з набору А слідуючим чином. Набір С рівний запереченню
набору А (тобто С=notA), а набір В є записом набору С в зворотньому
порядку.

Розділимо умовно наш 13-ти значний код на три групи

N YYYYYY GGGGGG.

Числа позначені в нашій схемі буквою G будуть кодуватися бітовими рядами
з набору С. Числа позначені Y кодуються бітовими рядами з групи А або В.
Група YYYYYY може приймати такі значення(Таблиця 5):

Таблиця 5.

№ набору №1 №2 №3 №4 №5 №6

0 A A A A A A

1 A A B A B B

2 A A B B A B

3 A A B B B A

4 A B A A B B

5 A B B A A B

6 A B B B A A

7 A B A B A B

8 A B A B B A

9 A B B A B A

Номер набору вибирається в залежності від значення числа N в нашій
схемі.

Як бачимо перше число, те що винесено за межі штрихкоду, кодується не
брусками штрихкоду, як інші числа, а комбінацією наборів наступних шести
чисел. Розглянемо приклад:

ШТРИХОВИЙ КОД: 8 000570 004257

1.Перший символ 8, тому група буде мати вигляд АВАВВА

2.Для чисел 000570 вибираємо бітові ряди зі слідуючих наборів: ABABBA, а
для чисел 004257 з набору C

3.Схемою нашого числа буде: 8 ABABBA CCCCCC

Штриховой код EAN8 формується подібно коду EAN13, з тією лише різницєю,
що замість пятизначных номерів для ідентифікації компанії і товару
використовуються, відповідно, трьохзначні і двозначні номери. Перші дві
цифри – номер країни, наступні три цифри – номер компанії, після цього
іде унікальний номер товару і остання цифра – контрольна.

Для знаходження контрольного числа в EAN8 використовується той же
механізм. Параметри тут будуть наступні:

МОДУЛЬ: 10

ВАГИ: 3131313

СУМА: Добутків.

Штрихові коди типів UPC є різновидами кодів EAN які використовуються
виключно на території Сполучених Штатів( аналогічно в Японії
використовують аналог цих кодів – JAN).

Рис: UPC-A Рис: UPC-E

9 червня 1997 року американська організація Uniform Code Council
прийняла рішення про розширення з 1січня 2005 року кодів UPC-A та UPC-E
на один сивол, тим самим привівши їх до стандартів EAN13 та EAN8.

Code39 та CODABAR

Сode39 – алфавітно-цифровий штриховий код. Він був розроблений в 1974
році, і був призначений щоб кодувати 43 символи: 26 букв латинської
абетки верхнього регістру, 10 цифр і 7 спеціальних символів(знаків). Він
може бути розширений на всі 128 ASCII символи(знаки), використовуючи два
символи, що задають схему кодування.

Кожний знак даних, кодований в Code39 складений з 5 чорних брусків
(барів) і 4 пробілів для загальної кількості 9 елементів. Кожний брусок
(бар) або пробіл є або ‘широким’ або ‘вузьким’, і 3 з 9 елементів завжди
широкі. Саме тому цей код і отримав свою назву.

Штриховий код включає тиху зону (10x-барів або 0.10 дюймів, що є
більшим), символ початку ‘*’, кодовані дані, символ зупинки ‘*’, і знову
тиха зона. Символ ‘*’ зірочки використовується тільки як код зупинки і
початку. X-бар – ширина самого маленького елементу в символі штрихового
коду. Висота брусків(барів) повинна бути принаймні 15-ти кратною
довжиною символу або 0,25 дюймів. Повна довжина символу дасться
рівнянням:

L=(C+2) (3N+6) X (+C+1)I

Де

L=довжина символу включаючи «тихі зони»

C=число знаків даних

X=X-бар (ширина самого маленького елементу)

N=Відношення широкого бруска до вузького

I=Ширина проміжку між знаками

Таблиця 6.

Character B1 S1 B2 S2 B3 S3 B4 S4 B5

1 1 0 0 1 0 0 0 0 1

2 0 0 1 1 0 0 0 0 1

3 1 0 1 1 0 0 0 0 0

4 0 0 0 1 1 0 0 0 1

5 1 0 0 1 1 0 0 0 0

6 0 0 1 1 1 0 0 0 0

7 0 0 0 1 0 0 1 0 1

8 1 0 0 1 0 0 1 0 0

9 0 0 1 1 0 0 1 0 0

0 0 0 0 1 1 0 1 0 0

To 1 0 0 0 0 1 0 0 1

B 0 0 1 0 0 1 0 0 1

C 1 0 1 0 0 1 0 0 0

D 0 0 0 0 1 1 0 0 1

And 1 0 0 0 1 1 0 0 0

F 0 0 1 0 1 1 0 0 0

G 0 0 0 0 0 1 1 0 1

H 1 0 0 0 0 1 1 0 0

I 0 0 1 0 0 1 1 0 0

J 0 0 0 0 1 1 1 0 0

K 1 0 0 0 0 0 0 1 1

L 0 0 1 0 0 0 0 1 1

M 1 0 1 0 0 0 0 1 0

N 0 0 0 0 1 0 0 1 1

Or 1 0 0 0 1 0 0 1 0

P 0 0 1 0 1 0 0 1 0

Q 0 0 0 0 0 0 1 1 1

R 1 0 0 0 0 0 1 1 0

S 0 0 1 0 0 0 1 1 0

T 0 0 0 0 1 0 1 1 0

U 1 1 0 0 0 0 0 0 1

V 0 1 1 0 0 0 0 0 1

W 1 1 1 0 0 0 0 0 0

X 0 1 0 0 1 0 0 0 1

Y 1 1 0 0 1 0 0 0 0

Z 0 1 1 0 1 0 0 0 0

– 0 1 0 0 0 0 1 0 1

. 1 1 0 0 0 0 1 0 0

space 0 1 1 0 0 0 1 0 0

* 0 1 0 0 1 0 1 0 0

$ 0 1 0 1 0 1 0 0 0

/ 0 1 0 1 0 0 0 1 0

+ 0 1 0 0 0 1 0 1 0

% 0 0 0 1 0 1 0 1 0

B1-B5 бруски

S1-S4 пробіли

широкий

вузький

В Code39 контрольне число є самим правим символом коду. Щоб обчислити
його, потрібно додати ціни всіх символів коду( Таблиця 7), і знайти
mod43 з суми. Так, якщо сума була 178, контрольне число буде 6.

Контрольна сума в Code39 використовується рідко, тому що Code39 весь час
перевіряє себе; як-тільки що-нибудь, не відповідає формату 3 з 9, воно
одразу буде відкинене як хибне.

Приклад: маємо текст “CODE-39”.

КРОК 1: Сума цін: 12+24+13+14+36+3+9=111

КРОК 2: 111mod43=25

КРОК 3: числу 25 відповідає символ “P”

Рядок після кодування: “CODE-39P”

Таблиця 7.

Cимвол Ціна Символ Ціна

0 0 M 22

1 1 N 23

2 2 O 24

3 3 P 25

4 4 Q 26

5 5 R 27

6 6 S 28

7 7 T 29

8 8 U 30

9 9 V 31

A 10 W 32

B 11 X 33

C 12 Y 34

D 13 Z 35

E 14 – 36

F 15 . 37

G 16 space 38

H 17 $ 39

I 18 / 40

J 19 + 41

K 20 % 42

L 21

Штрихові коди типу CODABAR будуються аналогічно до Code39. Відмінністю
між цими кодами є можливість кодувати в CODABAR тільки цифри в
поєднанні з символами: “$”, “-“, ”:”, ”/”, ”.”, “+”. Як і CODE 39,
штриховой код CODABAR використовує старт/стоп символи, в якості яких
можуть виступати літери “a”, “b”, “c” і “d” в будь-яких комбінаціях:
одна – для позначки початку коду і одна – кінця.

INTERLEAVED 2 OF 5

Інший тип штрихового коду – INTERLEAVED 2 OF 5, або ITF, подібно EAN –
коду складається тільки з цифр, але, на відмінність від останнього, може
мати різну довжину. Основне обмеження штрихового коду ITF – необхідність
використання парної кількості цифр, що зв’язано з сумісництвом зі
считувальними приладами. ITF код широко використовується в індустрії, де
цифрового коду достатньо для опису маркованого об’єкту. Зокрема, при
роздрібних продажах на Заході використовується так званий ‘зовнішній’
код. Цей код формується подібно коду EAN13, але, на відмінність від
нього, містить 14 цифр. Перші 3 цифри вказують на країну маркування (для
Великобританії – ‘050’), наступні 5 – номер компанії (‘Продукти від
Фреда’ – ‘44016’), після цього ідуть п’ять цифр, що вказують на
конкретний товар компанії (ці цифри повинні відрізнятися для різних
модифікацій товару), і остання, контрольна цифра одержується в
результаті арифметичних дій над тринадцятьма попередніми. Змінна довжина
коду ITF дозволяє включати в штриховой код конкретні характеристики
товару. Наприклад, при роздрібному продажі взуття штриховий код може
містити розмір виробів і т. д.

Щоб зрозуміти принцип кодування ITF-кодів, розглянемо спочатку коди
2of5, а потім – їхні відмінності від INTERLEAVED 2 OF 5. В кодах 2 of 5
кожний символ представлений в вигляді 5 ліній, поділлених 4 пробілами, з
1 кінцевим пробілом. 2 з цих 5 ліній жирні, а 3 – тонкі (звідси назва –
2 OF 5). Жирні лінії як правило товщі від тонких в 2.5 рази, але це
співвідношення може коливатися від 2,2:1 до 3:1.

В Таблиці 8 наведений принцип кодування (0 означає тонку лінію, 1 –
жирну):

Таблиця 8.

Цифрове значення Комбінація ліній

0 00110

1 10001

2 01001

3 11000

4 00101

5 10100

6 01100

7 00011

8 10010

9 01010

INTERLEAVED2OF5 відрізняється тільки тим, що для кодування цифр
використовуються і пробіли. Перші 5 ліній представляють першу цифру,
перші 5 пробілів – другу, наступні 5 ліній – третю, 5 пробілів –
четверту і т. д.. Отже, код повинен містити парну кількість цифр.

3. Створення самокорегуючого

штрихового коду

3.1 Постановка задачі

Задача, яка буде описана тут, була сформульована під час введення на
деякому великому підприємстві комп’ютеризованої системи пропусків. Кожен
працівник мав свій 6-ти значний ідинтифікаційний код, котрий разом з
фотографією та іменем працівника був нанесений на пластикову
картку-перепустку. Але для автоматизації контролю за переміщенням
працівників необхідно було забезпечити можливість зчитувати та
аналізувати інформацію з цих карток-перепусток і для ЕОМ. Таку
можливість можна забезпечити наявністю на перепустці магнітної стрічки
або ж штрихового коду. Магнітна стрічка в данній ситуіції не є
оптимальним вибором, в звязку з більшою вартістю як виготовлення такої
картки так і її обслуговування. Головною перевагою магнітної картки є
можливість збереження більшої інформації про власника, ніж при
застосуванні штрихового коду, але в нашому випадку такої потреби немає –
достатнь зберігати інформацію про ідинтифікаційний код робітника, та
можливо ще яку-небуть (рівень доступу, час роботи, і т.п.).

Таким чином оптимальним рішенням ціеї задачі є застосування штрихового
коду, який здатний кодувати 6-8 числових символів. Але використання
якого-небуть із загальновживаних типів штрихових кодів виявилося
ускладненим спицифікою використання карток-перепусток – через
необхідність весь час носити їх на одязі, картки поступово
забруднювалися, на їх поверхні з’являлися подряпини. Все це не впливало
на можливість читання інформації людиною, але при використанні сканерів
штрихових кодів кількість помилок з часом дуже швидко збільшувалась,
виникала потреба в заміні картки-перепустки.

Всі ці проблеми в кінці-кінців привели до формулювання слідуючої
постановки задачі: необхідно створити новий тип штрихового коду,
основними вимогами до якого є простота, не вибагливість до скануючого
пристрою, можливість кодування 6-8 числових символів та висока стійкість
до помилок.

3.2 Хід роботи

Розглянувши основні методи, що застосовуються до побудови штрихових
кодів, та зформулювавши постановку задачі, що стоїть перед нами, можемо
безпосередньо приступати до її розв’язання.

Введемо наступну термінологію:

Алфавітом штрихкоду назвемо множину символів з яких складається
інформація закодована в цьому штриховому коді.

Бітовий ряд – це послідовність скінченого числа “0” та “1” (в графічному
представленні – білих та чорних штрихів), яка задає один символ алфавіту
штрихкоду.

Вияснимо детальніще вимоги до нашого штрихового коду:

Вимога 1. Мінімальна кількість символів, яку повинен містити штрихкод –
6, але можливо це число варто збільшити до 7 або 8 символів вводячи
резервне або контрольне число.

Вимога 2. Алфавіт нашого штрихового коду складається тільки з 10 цифр
0,1, …,9. Одже на кодування одного символа нам знадобиться min 4 біти
24=16 (23<10). Насправді ця кількість в нас буде дещо більшою, за рахунок введення контрольних бітів та накладення деяких умов. Однією з таких умов буде наступна. Вимога 3. Для запобігання злиття двох сосідніх бітових рядів, необхідно щоб кожен з таких рядів розпочиновся з 0 та закінчувався 1-цею. Вимога 4. Велика кількість підряд йдучих однакових символів збільшує імовірнісь помилки. Тому слід накласти ще одну умову: в бітовому ряді не повинно бути підряд біль ніж 3 нулів чи одиничок. Вимога 5. Як зазначалося в вимозі 2, в наслідок виимог 3-4, на кодування одного символа потрібно 6 біт. Наш штриховий код буде забезпечено властивістю самовиправлення помилок, яка буде базуватися на методі Хеммінга. Для цього нам необхідно вияснити яку кількість бітів ми відведемо під перевірочні. Виходячи з відомої формули 2k>n+1, де n – загальна кількість бітів, k – кількість
провірочних бітів, m=n-k – кількість інформаційних бітів, отримуємо
наступну таблицю:

Таблиця 9.

k n m=k-n

1 1 0

2 3 1

3 7 4

4 15 11

5 31 26

6 63 57

7 127 120

8 255 247

Мінімальне число бітів в бітовому ряді 6, якщо під інформаційні ми
відведемо 26 біт, то ми зможемо кодувати 26/6=4 символи. Така кількість
є недостатньою для нашої задачі, тому виділимо під інформаційні 57
бітів, так ми зможемо кодувати до 57/6=9 символів, що є навіть
надлишково для нас.

В наступній таблиці записано всі можливі 6-ти значні бітові ряди, що
задовільняють нашим умовам.

Таблиця 10.

1 000101

2 000111

3 001001

4 001011

5 001101

6 010001

7 010011

8 010101

9 010111

10 011001

11 011011

12 011101

Цієї кількості бітових рядів достатньо, щоб кожному символові нашого
алфавіту штрихового коду поставити у відповідність один з них. Але
розглянувши також і матрицю кодових відстаней цих бітових
рядів(Таблиця11), мусимо зазначити деякі недоліки цього набору бітових
рядів.

Таблиця 11.

1 2 3 4 5 6 7 8 9 0 1 2

1 0 1 2 3 1 2 3 1 2 3 4 2

2 1 0 3 2 2 3 2 2 1 4 3 3

3 2 3 0 1 1 2 3 3 4 1 2 2

4 3 2 1 0 2 3 2 4 3 2 1 3

5 1 2 1 2 0 3 4 2 3 2 2 1

6 2 3 2 3 3 0 1 1 2 1 2 2

7 3 2 3 2 4 1 0 2 1 2 1 3

8 1 2 3 4 2 1 2 0 1 2 3 1

9 2 1 4 3 3 2 1 1 0 3 2 2

0 3 4 1 2 2 1 2 2 3 0 1 1

1 4 3 2 1 3 2 1 3 2 1 0 2

2 2 3 2 3 1 2 3 1 2 1 2 0

В різі виникнення однієї помилки в нашому штриховому коді, вона буде
виправлена за допомогою алгоритму Хеммінга. В разі виникнення двох
помилок метод Хеммінга перестає бути ефективним, в такій ситуації
принаймні повинно бути виявлено наявність помилки. Ми забезпечуємо
перевірку на наявність подвійних помилок, ввівши восьмий контрольний
символ. Він функціонально залежить від інших символів, і ця залежність
вибирається так щоб при зміні одного з перших семи символів, восьмий
контрольний також обов’язково змінився. Якщо при виникненні двох помилок
вони обі знаходяться в одному бітовому ряді, то наявність такої помилки
буде виявлено контрольним символом, але якщо ці помилки з’являться в
різних бітових рядах, тобто будуть змінені два числа в нашому коді, то
можливі такі комбінації символів коли помилка не буде виявлена взагалі.
Для запобігання таких помилок набір бітових рядів потрібно підібрати
так, щоб матриця кодових відстаней цього набору не містила одиниць. Тоді
при виникненні двох помилок в різних бітових рядах, ці новоутворені
бітові ряди не будуть належати нашому наборові, і таким чином буде
виявлено наявність помилок. В разі, якщо матриця кодових відстаней не
буде містити одиниць, для того щоб було згенеровано помилку, яка не
виявиться, необхідно, щоб ці помилки виникли по дві в двох різних
бітових рядах. Тобто вивівши з матриці кодових відстаней одиниці, ми
значно покращимо стійкість до помилок нашого коду.

Але тут виникає проблема: для того щоб вивести з матриці кодових
відстаней одиниці, потрібно скоротити набір бінарних рядів, але тоді
цього набору буде замало щоб поставити один бітовий ряд у відповідність
одному симолу нашого алфавіту. Ми приходимо до потреби збільшення
довжини наших бітових рядів з 6-ти до 7-ми символів.

57/7=8. Це також задовільняє нашим вимогам. Ми зможемо кодувати до
восьми символів. В наступній таблиці записано всі можливі бітові ряди,
що задовольняють нашим умовам. Нагадаємо, що алфавіт нашого штрихового
коду складається з 10 символів, а оскільки допустимих бінарних рядів 22
то в нас тепер є змога розділивши їх на дві групи, кодувати один з наших
символів не бітовим рядом, а належністю бітових рядів інших символів до
тієї чи іншої групи( Детально цей метод кодування було описано під час
опису типу штрихкоду EAN-13).

Таблиця 12.

1 0001001

2 0001011

3 0001101

4 0010001

5 0010011

6 0010101

7 0010111

8 0011001

9 0011011

10 0011101

11 0100011

12 0100101

13 0100111

14 0101001

15 0101011

16 0101101

17 0110001

18 0110011

19 0110101

20 0110111

21 0111001

22 0111011

За рахунок цього можна або додати до нашого коду дев’ятий символ без
збільшення кількості бітів в штриховому коді( тим самим зменшивши
надлишковість нашого коду), або, залишивши наш код 8-ми символьним,
зменшити кількість біт, що будуть кодувати цей код (тим самим також
зменшивши надлишковість).

Але в нашій задачі основною вимогою до штрихового коду є не
мінімізація надлишковості, а збільшення стійкості коду до помилок. Тому
нам доведеться відмовитися від запропонованого вище варіанту розподілу
бітових послідовностей на дві групи, з метою запобігання тих самих
помилок, що були описані вище. Як бачимо матриця кодових відстаней
бітових рядів (Табл.13) також містить одиниці.

Таблиця 13.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

1 0 1 1 2 3 3 4 1 2 2 3 3 4 1 2 2 3 4 4 5 2 3

2 1 0 2 3 2 4 3 2 1 3 2 4 3 2 1 3 4 3 5 4 3 2

3 1 2 0 3 4 2 3 2 3 1 4 2 3 2 3 1 4 5 3 4 3 4

4 2 3 3 0 1 1 2 1 2 2 3 3 4 3 4 4 1 2 2 3 2 3

5 3 2 4 1 0 2 1 2 1 3 2 4 3 4 3 5 2 1 3 2 3 2

6 3 4 2 1 2 0 1 2 3 1 4 2 3 4 5 3 2 3 1 2 3 4

7 4 3 3 2 1 1 0 3 2 2 3 3 2 5 4 4 3 2 2 1 4 3

8 1 2 2 1 2 2 3 0 1 1 4 4 5 2 3 3 2 3 3 4 1 2

9 2 1 3 2 1 3 2 1 0 2 3 5 4 3 2 4 3 2 4 3 2 1

10 2 3 1 2 3 1 2 1 2 0 5 3 4 3 4 2 3 4 2 3 2 3

11 3 2 4 3 2 4 3 4 3 5 0 2 1 2 1 3 2 1 3 2 3 2

12 3 4 2 3 4 2 3 4 5 3 2 0 1 2 3 1 2 3 1 2 3 4

13 4 3 3 4 3 3 2 5 4 4 1 1 0 3 2 2 3 2 2 1 4 3

14 1 2 2 3 4 4 5 2 3 3 2 2 3 0 1 2 2 3 3 4 1 2

15 2 1 3 4 3 5 4 3 2 4 1 3 2 1 0 2 3 2 4 3 2 1

16 2 3 1 4 5 3 4 3 4 2 3 1 2 2 2 0 3 4 2 3 2 3

17 3 4 4 1 2 2 3 2 3 3 2 2 3 2 3 3 0 1 1 2 1 2

18 4 3 5 2 1 3 2 3 2 4 1 3 2 3 2 4 1 0 2 1 2 1

19 4 5 3 2 3 1 2 3 4 2 3 1 2 3 4 2 1
2???????????????????????????????????????????????????????????????????????
??????

Виберемо з 22-х бітових рядів десять таких, щоб їх матриця кодових
відстаней не містила одиниць. Отримаємо Таблицю 14.

Таблиця 14.

0 0001001

1 0010001

2 0010111

3 0011011

4 0011101

5 0100111

6 0101011

7 0101101

8 0110011

9 0110101

Матриці кодових відстаней:

Таблиця 15.

0 1 2 3 4 5 6 7 8 9

0 0 2 4 2 2 4 2 2 4 4

1 2 0 2 2 2 4 4 4 2 2

2 4 2 0 2 2 2 4 4 2 2

3 2 2 2 0 2 4 2 4 2 4

4 2 2 2 2 0 4 4 2 4 2

5 4 4 2 4 4 0 2 2 2 2

6 2 4 4 2 4 2 0 2 2 4

7 2 4 4 4 2 2 2 0 4 2

8 4 2 2 2 4 2 2 4 0 2

9 4 2 2 4 2 2 4 2 2 0

Наш штриховий код буде мати слідуючу структуру:

0ххххх10ххххх10ххххх10ххххх10ххххх10ххххх10ххххх10ххххх1nnnnnn

Вона містить один невеликий недолік, останні шість бітів можуть
неправильно зчитуватися. Наприклад: а) вище ми накладали обмеження на
кількість однакових підряд йдучих символів “0” чи “1” , на комбінацію
nnnnnn в данному випадку таке обмеження не поширюється; б) в разі, якщо
остнній байт чи байти будуть рівні “1”, то при графічному представленні
цього коду вони будуть втрачені, оскільки зіллються з “тихою зоною”. Щоб
запабігти цим небажанним явищам, введемо додаткові нульові біти в кінець
нашого коду. Отримаємо код наступної структури:

0ххххх10ххххх10ххххх10ххххх10ххххх10ххххх10ххххх10ххххх101nn01nn01nn010

В цьому коді всі вище перераховані недоліки усунуто.

Потрібно також для нашого коду вибрати алгоритм знаходження
контрольного числа. Запозичимо алгоритм з коду типу EAN. Тоді вагами
будуть “3 1 3 1 3 1 3”, а контрольне число буде рівне mod10 від зваженої
суми.

Таким чином створивши штриховий код( назвемо його НЕМ-8), було
розвязано поставлену перед нами задачу. Нам залишилося тільки перевірити
єфективність цього коду. Для початку підрахуємо ентропію нашого коду. Не
важко пересвідчитися що НЕМ-8 складається з 71 біта, кількість
комбінацій чисел які можна утворити 10 міліонів ( 107 ), оскільки восьме
число залежить тільки від перших семи, ми його не враховуємо. Кількість
інформації шо несе в собі штрихкод НЕМ-8 рівна I(a)=log(107). Вище була
наведена формула для знаходження величини надлишковості коду,
використаємо її тепер.

в нашому випадку алфавіт двозначний L=2, кількість бітів n=71 тому

Як бачимо коефіцієнт надлишковості досить великий, для порівняння
надлишковість коду EAN-13 рівна

,

що також не мало. Але завдяки цій надлишковості ці коди стають більш
стійкими до помилок, що для нас більш важливо ніж надмірність
інформації. Стійкість до помилок нам ще необхідно буде перевірити. Для
цього необхідно провести статистичні дослідження по виправленню та
виявленню помилок. Для цих досліджень необхідно створити прикладну
програму, яка б генерувала для заданого коду певну кількість помилок і
намагалася б їх виявити та виправити. Ця програма та її результати буде
розглянуть нижче.

4. Результати та їх аналіз

4.1. Початкові результати

Результати отримані при виконанні цієї дипломної роботи можна умовно
разділити на початкові та кінцеві. Початкові результати були отримані
первоначально, при використанні програми Oldkoran. Отримавши їх:

Кількість помилок в коді 1

Кількість згенерованих помилкових кодів 71е7

В тому числі: виправлено 71е7 100%

В тому числі: виявлено але не виправлено 0 0%

В тому числі: не виявлено 0 0%

Кількість помилок в коді 2

Кількість згенерованих помилкових кодів 2.485е10

В тому числі: виправлено 1.465е10 58.9537%

В тому числі: виявлено але не виправлено 1.008е10 40.5707%

В тому числі: не виявлено 1.1818е8 0.4756%

було виявлено деяку недосконалість коду. А саме – при генерації в коді
двох помилок бло виявлено деякі можливі комбінації при яких програма
була не в змозі навіть виявити помилку. І хоча таких комбінацій дуже
мало (всього як бачимо 0.48%), тобто імовірність того, що саме в цьому
коді виникне саме ця комбінація помилок – мізерна. Але тим не менше цю
ваду необхідно було виправити.

4.2. Кінцевий результат

Проаналізувавши початкові результати, їх недоліки, та причини що їх
викликали було вирішено замінити таблицю кодування чисел на таку, для
якої б матриця кодових відстаней не містила одиниць. Було отримано
таблицю 14. Як бачимо з нових результатів:

Кількість помилок в коді 1

Кількість згенерованих помилкових кодів 71е7

В тому числі: виправлено 71е7 100%

В тому числі: виявлено але не виправлено 0 0%

В тому числі: не виявлено 0 0%

Кількість помилок в коді 2

Кількість згенерованих помилкових кодів 2.485е10

В тому числі: виправлено 1.465е10 58.9537%

В тому числі: виявлено але не виправлено 1.02е10 41.0463%

В тому числі: не виявлено 0 0%

попередню ваду було усунуто і на цей раз помилок в коді які б не
виявлялися нема. Крім того проаналізувавши матрицю кодових відстаней
(табл.15), бачимо що навіть при генеруванні 3 помилок в коді, всі
помилкові коди або будуть виправлені або хоча б виявлені, шо свідчить
про високу ефективність коду НЕМ-8.

5. Програма

5.1 Iнструкція користувача

В ході віконання цієї дипломної роботи було створено пакет з чотирьох
програм: Moonbug, Koran, Oldkoran та Hem8. В цьому розділі буде
приведено їх опис та інструкції користувача.

Koran та Oldkoran по суті це одна й та сама програма, тому в цій роботі
приведено лістинг тільки першої. Різниця між цими програмами тільки в
таблиці кодування чисел коду. Koran використовує для кодування таблицю
бітових рядів матриця кодових відстаней яких не містить одиниць, про
необхідність цього наголошувалось в попередньому розділі. Цю
необхідність добре було видно при порівнянні результатів роботи цих двох
програм. Оldkoran використовує для кодування таблицю бітових рядів,
матриця кодових відстаней яких містить одиниці, що збільшує йомовірність
появи таких помилок, які не тільки не будуть виправлені, а й не будуть
виявлені.

Koran та Oldkoran це DOS-програми, створені за допомогою компілятора
Borland C++ 3.1. Запустивши їх побачимо слідуюче меню.

Der Diplomprojekt v.1.2 ‘Koran’ Mishel Kozak

1. Beginn prufung

2. Fortsetzen prufung

?

Перший пункт – розпочати тест, другий – продовжити. В разі якщо ми
починаемо тест, вибираємо перший пункт натиснувши “1”, після якого
програма поцікавиться іменем файлу в який буде записуватися інформація
стосовно нашого тесту:

Der Diplomprojekt v.1.2 ‘Koran’ Mishel Kozak

Einfurst der Filename(*.krn): [ ]

Після вводу імені файла, програмі необхідно вказати з якого коду
починати тестування:

Der Diplomprojekt v.1.2 ‘Koran’ Mishel Kozak

Einfurst anfangs kode: [ ]

Програма перевірятиме вся коди починаючи з введеного. Для повного тесту
необхідно вказати код 0000000. Можливість введення початкового коду
передбачена на випадок якщо тестування буде проводитися на кілкох ЕОМ.
Ввівши початковий код програма виводить новий запит:

Der Diplomprojekt v.1.2 ‘Koran’ Mishel Kozak

Einfurst anfangs kode: [1111111]

Einfurst der Anzahl fehler(1/2): [ ]

Їй необхідно вказати кількість помилок яку вона повинна генерувати.
Після вводу кількості помилок програма розпочинає тестування. В файлі
котрий ми вказали буде записано всю інформацію яка буде необхідна для
продовження раніше розпочатого, але перерваного тесту. В файлі
зберігається останній перевірений код, кількість помилок яка генерується
в коді, та вся статистика досліду.

Якщо тест нами було розпочато раніше і зараз нам потрібно його
продовжити, то в початковому меню вибираємо другий пункт нитиснувши “2”.
Програма поцікавиться іменем файлу в якому зберігається наш тест.

Der Diplomprojekt v.1.2 ‘Koran’ Mishel Kozak

Einfurst der Filename(*.krn): [ ]

На відміну від випадку в першому пункті, тут очікується що такий файл
уже існує, інакше програма не розпочне тестування. Решту інфомації
програма отримає з цього файла й розпочне тестування.

Під час тестування на дисплеї ЕОМ періодично виводиться проміжкова
інформація про процес тестування.

Der Diplomprojekt v.1.2 ‘Koran’ Mishel Kozak

May 26 15:38:00 1999

Code: 0 0 0 0 2 6 8 8

Type error: 2

_ 1_ 1_ 1_ 1_ 1_ 1_ 1_ 1_1 _1 _1
_1_

Real___ __ ___ __ ___ __ ___ __ __ _ _ _ _ _ __ _ __ _ _ _ __
_ _

error___ __ ___ __ ___ __ ___ __ __ _ _ _ _ _ __ _ __ _ _ _ __
_ _

Total error: 668465

= fatal error: 274380 41.046278%

= corectly error: 394085 58.953722%

= warning error: 0 0%

For exit press ‘q’…

Ми можемо бачити який саме зараз код тестується, скільки помилкових
кодів було згенеровано, скільки з них виявлено, виправлено, чи не
виявлено. останні три показника демонструються в кількісному виді та в
відсотковому відношенні один до одного.

Програма перебирає всі коди починаючи з початкового, який ми вказали на
початку тесту. Для кожного коду програма генерую всі можливі помилки.
Оскільки наш код складається з 71 біта, то в разі генерації однієї
помилки буде згенеровано 71 помилковий код, а в випадку генерації двох
помилок 1+2+3+ … +69+70=70*71/2=2485. Згенерувавши помилковий код
програма намагається виявити та виправити в ньому помилку. При цьому
можливі три випадки:

– помилку виявлено та виправлено;

– помилку виявлено;

– помилку не виявлено.

перші два випадки є допустимими, а третій ні, бо він означає, що код
було зчитано неправильно, але ЕОМ про це непідозрює. Така помилка не
можлива при наявності одного помилкового біту в коді. Як буде видно з
результатів програм Oldkoran допускає всі три випадки, в той час як
Koran при двох помилках в коді третьго випадку не допускає. Глянувши на
матрицю кодових відстаней бачимо, що й при генерації трьох помилок в
коді така ситуація неможлива.

Moonbug. Ця програма створена за допомогою Borland C++ Builder4.0 для
Win32. По своїй суті ця програма є аналогом програми Koran. Вона була
створена як демонстраційна програма. Основною відмінністю її від Koran є
дружній інтерфейс користувача, створений на основі Win32. Але в наслідок
цього в програми різко знижена швидкодія, через що використання її для
повноцінного тестування всього набору кодів не рекомендована.

Для початку роботи, після запуску програми необхідно натиснути кнопку
“Start”. Після цього ввести стартовий код, та кількість помилок яка
повинна генеруватися (див. малюнок). Після внесення стартової
інформації, натиснувши кнопку “Test”, розпочинаємо тестування.

Через певний проміжок часу (значення таймера демонструється в
відповідному полі) статистика нашого тесту обновляється, виводячи на
екран інформацію про кількість згенерованих помилок та кількість не
виявлених, виправлених і тільки виявлених помилок. Ця сама інформація
відображається в виді кругової діаграми(див малюнок).

Частоту обновлення інформації можна змінювіти за допомогою відповідного
повзунка на головному вікні. Ця можливість передбачина для покращення
швидкодії програми, оскільки вивід на екран інформації забирає деяку
кількість часу.

Обновити статистику тесту можна й не дочікуючися завершення відліку
таймера, а просто вибравши в меню пункт “статистика”. Роботу програми
можна тимчасово призупинити натиснувши для цього кнопку “Stop” на
головному вікні, або вибравши в меню аналогічний пункт. Крім того в меню
є ще два пункти – “початок”, він є аналогом кнопки “Start”, та пункт
“Програма”. Вибравши цей пункт можна отримати інформацію про програму:

Hem8. Ця програма створена для генерування штрихового коду типу НЕМ-8.
Вона створена за допомогою Borland C++ Builder4.0 як програма для Win32.
Зовнішній вид програми зображено на малюнку.

При використанні програми користувач повинен ввести 7-ми значний код.
Після цього натиснути кнопку генерації коду. Програма обчислює
контрольне восьме число коду й відображає зовнішній вид штрихового коду,
що відповідає введеному числовому значенню.

Текст програм

Проект MoonBug

MOONBUG.CPP

//———————————————————————-

#include

#include “Barclass.h”

#pragma hdrstop

USERES(“MoonBug.res”);

USEFORM(“Unit1.cpp”, Form1);

USEFILE(“BarClass.h”);

USEUNIT(“Barclass.cpp”);

USEFORM(“Unit2.cpp”, AboutBox);

//———————————————————————-

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

{

try

{

Application->Initialize();

Application->CreateForm(__classid(TForm1), &Form1);

Application->CreateForm(__classid(TAboutBox),
&AboutBox);

Application->Run();

}

catch (Exception &exception)

{

Application->ShowException(&exception);

}

return 0;

}

//———————————————————————-

UNIT1.H

//———————————————————————-

#ifndef Unit1H

#define Unit1H

//——————

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include “Unit2.h”

//———————————————————————-

class TForm1 : public TForm

{

__published: // IDE-managed Components

TOpenDialog *OpenDialog1;

TMainMenu *MainMenu1;

TMenuItem *N1;

TMenuItem *N2;

TMenuItem *N3;

TMenuItem *N4;

TMenuItem *N5;

TMenuItem *N6;

TStatusBar *StatusBar1;

TActionList *ActionList1;

TEditCopy *EditCopy1;

TAction *Action1;

TAction *Action2;

TSaveDialog *SaveDialog1;

TPanel *Panel1;

TLabel *Label1;

TMaskEdit *MaskEdit1;

TCheckBox *CheckBox1;

TPanel *Panel2;

TCheckBox *CheckBox2;

TComboBox *ComboBoxErr;

TBitBtn *Stop;

TBitBtn *Start;

TBitBtn *BitBtn1;

TTimer *Timer1;

TTrackBar *TrackBar1;

TChart *Chart1;

TPieSeries *Series1;

TEdit *TextTimer;

TLabel *Label2;

TGroupBox *GroupBox1;

TEdit *Edit1Gen;

TLabel *Label3;

TLabel *Label4;

TEdit *Edit2war;

TLabel *Label5;

TEdit *Edit3notfatal;

TLabel *Label6;

TEdit *Edit4fatal;

TLabel *Label7;

void __fastcall FormInfo();

void __fastcall N2Click(TObject *Sender);

void __fastcall ButtonStartClick(TObject *Sender);

void __fastcall N4Click(TObject *Sender);

void __fastcall MaskEdit1Exit(TObject *Sender);

void __fastcall ComboBoxErrExit(TObject *Sender);

void __fastcall MaskEdit1Change(TObject *Sender);

void __fastcall StopClick(TObject *Sender);

void __fastcall BitBtn1Click(TObject *Sender);

void __fastcall Timer1Timer(TObject *Sender);

void __fastcall TrackBar1Change(TObject *Sender);

void __fastcall N5Click(TObject *Sender);

void __fastcall N6Click(TObject *Sender);

private: // User declarations

public: // User declarations

__fastcall TForm1(TComponent* Owner);

};

//———————————————————————

extern PACKAGE TForm1 *Form1;

//———————————————————————

#endif

UNIT1.CPP

//———————————————————————-

#include

#pragma hdrstop

#include “Unit1.h”

#include “Barclass.h”

//——————————————————————–

#pragma package(smart_init)

#pragma resource “*.dfm”

TBarCode* MyBarCode = new(TBarCode);

TForm1 *Form1;

//———————————————————————-

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

}

//———————————————————————-

void __fastcall TForm1::N2Click(TObject *Sender)

{

if(Form1->N2->Checked==false)

{

Form1->N2->Checked=true;

Form1->N3->Checked=false;

}

else

{

Form1->N2->Checked=false;

Form1->N3->Checked=true;

}

}

//———————————————————————-

void __fastcall TForm1::ButtonStartClick(TObject *Sender)

{

if (Form1->N2->Checked==true)

{

// OpenDialog1->Execute();

Form1->MaskEdit1->Enabled=true;

Form1->MaskEdit1->ParentColor=false;

Form1->MaskEdit1->Color=clWhite;

Form1->Start->Enabled=false;

Form1->MaskEdit1->TabOrder=0;

Form1->ActiveControl=MaskEdit1;

}

else

{

};

}

//———————————————————————-

void __fastcall TForm1::N4Click(TObject *Sender)

{

if (SaveDialog1->Execute()) Close();

}

//———————————————————————-

void __fastcall TForm1::MaskEdit1Exit(TObject *Sender)

{

Form1->MaskEdit1->Enabled=false;

char *Buffer = new char[9]; //Creates Buffer dynamic variable

Form1->MaskEdit1->GetTextBuf(Buffer,8);

MyBarCode->SetUp(Buffer);

Form1->MaskEdit1->ParentColor=true;

Form1->CheckBox1->Checked=true;

Form1->ComboBoxErr->Enabled=true;

}

//———————————————————————-

void __fastcall TForm1::ComboBoxErrExit(TObject *Sender)

{

Form1->ComboBoxErr->Enabled=false;

Form1->CheckBox2->Checked=true;

MyBarCode->SetCountErr(StrToInt(Form1->ComboBoxErr->Text));

}

//———————————————————————-

void __fastcall TForm1::MaskEdit1Change(TObject *Sender)

{

Form1->ComboBoxErr->Enabled=true;

}

//———————————————————————-

void __fastcall TForm1::StopClick(TObject *Sender)

{

Form1->Timer1->Enabled=false;

Form1->Start->Enabled=true;

Form1->Chart1->Visible=false;

}

//———————————————————————-

void __fastcall TForm1::BitBtn1Click(TObject *Sender)

{

Form1->Timer1->Enabled=true;

Form1->Chart1->Visible=true;

}

//———————————————————————-

void __fastcall TForm1::Timer1Timer(TObject *Sender)

{

Form1->TextTimer->Text=IntToStr(MyBarCode->Pausa);

Form1->Timer1->Enabled=false;

MyBarCode->Test();

if (MyBarCode->Pausa==0)

{

Form1->FormInfo();

MyBarCode->Info();

MyBarCode->Pausa=Form1->TrackBar1->Position*100;

}

else

{

};

MyBarCode->Pausa–;

Form1->Timer1->Enabled=true;

}

//———————————————————————-

void __fastcall TForm1::TrackBar1Change(TObject *Sender)

{

MyBarCode->Pausa=Position*100;

}

//———————————————————————-

//———————————————————————-

void __fastcall TForm1::FormInfo()

{

int pf,pn,pw;

pf=(MyBarCode->GetCountErr(1)*100)/MyBarCode->GetCountErr(0);

pn=(MyBarCode->GetCountErr(2)*100)/MyBarCode->GetCountErr(0);

pw=(MyBarCode->GetCountErr(3)*100)/MyBarCode->GetCountErr(0);

Form1->Chart1->Visible=true;

Series1->Clear();

Series1->ExplodeBiggest;

Series1->AddPie( pf, “% тш тыхэю” , clRed ) ;

Series1->AddPie( pn, “% тшяЁртыхэю”, clBlue ) ;

Series1->AddPie( pw, “% эх тш тыхэю”, clGreen ) ;

Form1->Edit1Gen->Text=FloatToStr(MyBarCode->GetCountErr(0));

Form1->Edit2war->Text=FloatToStr(MyBarCode->GetCountErr(3));

Form1->Edit3notfatal->Text=FloatToStr(MyBarCode->GetCountErr(2));

Form1->Edit4fatal->Text=FloatToStr(MyBarCode->GetCountErr(1));

};

void __fastcall TForm1::N5Click(TObject *Sender)

{

Form1->FormInfo();

}

//———————————————————————-

void __fastcall TForm1::N6Click(TObject *Sender)

{

AboutBox->ShowModal();

}

//———————————————————————-

UNIT2.H

//———————————————————————-

#ifndef Unit2H

#define Unit2H

//———————————————————————-

#include <vcl\System.hpp>

#include <vcl\Windows.hpp>

#include <vcl\SysUtils.hpp>

#include <vcl\Classes.hpp>

#include <vcl\Graphics.hpp>

#include <vcl\Forms.hpp>

#include <vcl\Controls.hpp>

#include <vcl\StdCtrls.hpp>

#include <vcl\Buttons.hpp>

#include <vcl\ExtCtrls.hpp>

//———————————————————————-

class TAboutBox : public TForm

{

__published:

TPanel *Panel1;

TImage *ProgramIcon;

TLabel *ProductName;

TLabel *Version;

TLabel *Copyright;

TLabel *Comments;

TButton *OKButton;

private:

public:

virtual __fastcall TAboutBox(TComponent* AOwner);

};

//———————————————————————-

extern PACKAGE TAboutBox *AboutBox;

//———————————————————————

#endif

UNIT2.CPP

//————————————————————–

#include

#pragma hdrstop

#include “Unit2.h”

//———————————————————————

#pragma resource “*.dfm”

TAboutBox *AboutBox;

//———————————————————————

__fastcall TAboutBox::TAboutBox(TComponent* AOwner)

: TForm(AOwner)

{

}

//———————————————————————

BARCLASS.H

class TBarCode {

private:

char MyCode[8];

int CodeInt[8];

int CountErr;

char MasBit[71];

char ErrBit[71];

double CountGenErr;

double FatalErr;

double NotFatal;

double WarnErr;

void CheckSum();

void CreatBitCode();

bool Next();

void GenError();

void Control();

// double Error;

// double FatalErr;

// double NotFatalError;

// ¦юф •ю ъюфє¦Є№ё

/* unsigned char pcode[8];

unsigned char textdata[25];

char cod[8];

char flag;

char f1;

char f2;

char masbit[71];

char errbit[71];

unsigned char ecode[8];

double err;

double ferr;

double nferr;

double warning;

*/

public: TBarCode();

void SetUp(char*);

void Test();

void SetCountErr(int);

double GetCountErr(int);

void Info();

int Pausa;

/* void bitcode();

void checksum();

void init(char*,char);

void getmytime();

void save(char*,BarCode*);

void read(char*,BarCode*);

short next();

void test();

void info();

void gen_error();

*/

};

BARCLASS.CPP

#include “Barclass.h”

short Tabl[10][7]=

{ {0,0,0,1,0,0,1},

{0,0,1,0,0,0,1},

{0,0,1,0,1,1,1},

{0,0,1,1,0,1,1},

{0,0,1,1,1,0,1},

{0,1,0,0,1,1,1},

{0,1,0,1,0,1,1},

{0,1,0,1,1,0,1},

{0,1,1,0,0,1,1},

{0,1,1,0,1,0,1}};

short CheckTabl[56][6]=

{

{1,1,1,1,1,1}, //*

{0,0,0,0,0,0},

{1,0,0,0,0,0},

{0,1,0,0,0,0},//1

{0,0,1,0,0,0},

{0,0,0,1,0,0},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{0,0,0,0,1,0},

{0,0,0,0,0,1},

{1,1,0,0,0,0},//2

{1,0,1,0,0,0},

{1,0,0,1,0,0},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{1,0,0,0,1,0},

{1,0,0,0,0,1},

{0,1,1,0,0,0},//3

{0,1,0,1,0,0},

{0,1,0,0,1,0},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{0,1,0,0,0,1},

{0,0,1,1,0,0},

{0,0,1,0,1,0},//4

{0,0,1,0,0,1},

{0,0,0,1,1,0},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{0,0,0,1,0,1},

{0,0,0,0,1,1},

{1,1,1,0,0,0},//5

{1,1,0,1,0,0},

{1,1,0,0,1,0},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{1,1,0,0,0,1},

{1,0,1,1,0,0},

{1,0,1,0,1,0},//6

{1,0,1,0,0,1},

{1,0,0,1,1,0},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{1,0,0,1,0,1},

{1,0,0,0,1,1},

{0,1,1,1,0,0},//7

{0,1,1,0,1,0},

{0,1,1,0,0,1},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{0,1,0,1,1,0},

{0,1,0,1,0,1},

{0,1,0,0,1,1},//8

{0,0,1,1,1,0},

{0,0,1,1,0,1},

{1,1,1,1,1,1}, //*

};

//———————————–

void TBarCode::SetUp(char* Text)

{

for(int i=0;i<7;i++) MyCode[i]=Text[i];

}

//————————————

TBarCode::TBarCode()

{

Pausa=500;

}

//————————————

void TBarCode::Test()

{

// SetCountErr();

CheckSum();

CreatBitCode();

GenError();

}

//———————————–

void TBarCode::CheckSum() //+

{

for(int i=0;i<7;i++) CodeInt[i]=MyCode[i]-48;

CodeInt[7]=(CodeInt[0]+CodeInt[2]+CodeInt[4]+CodeInt[6]+3*(CodeInt[1]+Co
deInt[3]+CodeInt[5]))%10;

MyCode[7]=CodeInt[7]+48;

}

//————————————

void TBarCode::CreatBitCode()

{

unsigned int s;

short TmpMas[6];

for(int i=0;i<8;i++)

{

for(int j=0;j<7;j++)

{

MasBit[i*7+j]=Tabl[(CodeInt[i])][j];

};

};

for(int i=0;i<6;i++)

{

s=0;

for(int j=0;j<56;j++)

{

if(CheckTabl[j][i]==0)

{

s+=MasBit[j];

};

};

TmpMas[i]=s%2;

};

MasBit[56]=0;

MasBit[57]=1;

MasBit[58]=TmpMas[0];

MasBit[59]=TmpMas[1];

MasBit[60]=0;

MasBit[61]=1;

MasBit[62]=TmpMas[2];

MasBit[63]=TmpMas[3];

MasBit[64]=0;

MasBit[65]=1;

MasBit[66]=TmpMas[4];

MasBit[67]=TmpMas[5];

MasBit[68]=0;

MasBit[69]=1;

MasBit[70]=0;

for(int i=0;i<71;i++) ErrBit[i]=MasBit[i];

}

// T CodeInt[8] 8-ьш чэрўэх ўшёыю

// чс¦ы№°шью щюую эр юфшэшЎ¦

// T Ёрч¦  ъ•ю ўшёыю фюё уыю 99999999 яютхЁЄр¦Є№ё  чэрўхээ  true.

bool TBarCode::Next()

{

if(CodeInt[6]!=9) { CodeInt[6]++; MyCode[6]++;}

else

{

if(CodeInt[5]!=9) { CodeInt[5]++; MyCode[5]++; }

else

{

if(CodeInt[4]!=9) {CodeInt[4]++;MyCode[4]++;}

else

{

if(CodeInt[3]!=9) {CodeInt[3]++;MyCode[3]++;}

else

{

if(CodeInt[2]!=9) {CodeInt[2]++;MyCode[2]++;}

else

{

if(CodeInt[1]!=9) {CodeInt[1]++;MyCode[1]++;}

else

{

if(CodeInt[0]!=9) {CodeInt[0]++;MyCode[0]++;}

else return(false);

CodeInt[1]=0;

MyCode[1]=’0′;

};

CodeInt[2]=0;

MyCode[2]=’0′;

};

CodeInt[3]=0;

MyCode[3]=’0′;

};

CodeInt[4]=0;

MyCode[4]=’0′;

};

CodeInt[5]=0;

MyCode[5]=’0′;

};

CodeInt[6]=0;

MyCode[6]=’0′;

};

return(true);

}

//————————————

void TBarCode::SetCountErr(int Err) { CountErr=Err; }

//————————————————–

double TBarCode::GetCountErr(int TypeErr)

{

switch (TypeErr) {

case 0: return(CountGenErr);break;

case 1: return(FatalErr);break;

case 2: return(NotFatal);break;

case 3: return(WarnErr);break;

default: return(0);

}

}

//————————————————–

void TBarCode::GenError()

{

int f1,f2;

if(CountErr==1)

{

f1=1;

do

{

if(ErrBit[f1]==0) ErrBit[f1]=1;

else if(ErrBit[f1]==1) ErrBit[f1]=0;

Control();

if(ErrBit[f1]==0) ErrBit[f1]=1;

else if(ErrBit[f1]==1) ErrBit[f1]=0;

f1++;

} while(f1<72);

};

if(CountErr==2)

{

f1=1;

do

{

f2=f1+1;

do

{

if(ErrBit[f1]==0) ErrBit[f1]=1;

else if(ErrBit[f1]==1) ErrBit[f1]=0;

if(ErrBit[f2]==0) ErrBit[f2]=1;

else if(ErrBit[f2]==1) ErrBit[f2]=0;

Control();

if(ErrBit[f1]==0) ErrBit[f1]=1;

else if(ErrBit[f1]==1) ErrBit[f1]=0;

if(ErrBit[f2]==0) ErrBit[f2]=1;

else if(ErrBit[f2]==1) ErrBit[f2]=0;

f2++;

} while(f2<72);

f1++;

} while(f1<71);

};

}

//—————————————————-

void TBarCode::Info() //+

{

}

//———————————–

void TBarCode::Control()

{

unsigned char ErrCode[8];

short TmpMas[6];

short i,j,s;

short Check[6]={1,1,1,1,1,1};

char TestCod[8];

char Test[71];

char TestTab[7];

CountGenErr++;

for(i=0;i<71;i++)

Test[i]=ErrBit[i];

for(i=0;i<8;i++)

{

Test[i*7]=0; //

Test[i*7+6]=1; //

}; //

Test[56]=0; //

Test[57]=1; //

Test[60]=0; //

Test[61]=1; //

Test[64]=0; //

Test[65]=1; //

Test[68]=0; //

Test[69]=1; //

Test[70]=0; //

for(i=0;i<6;i++) //

{

s=0;

for(j=0;j<56;j++)

{

if(CheckTabl[j][i]==0)

{

s+=Test[j];

};

};

TmpMas[i]=s%2;

};

for(j=0;j<3;j++)

{

if(TmpMas[j*2]!=Test[58+j*4]) Check[j*2]=0;

if(TmpMas[j*2+1]!=Test[59+j*4]) Check[j*2+1]=0;

};

short n=0;

for(i=0;i<6;i++) { if(Check[i]==0) { n++; }; }; if(n>1) n=0;

else n=1;

switch (n)

{

case 0:

{

for(i=0;i<56;i++)

{

short eq=1;

for(j=0;j<6;j++)

{

if(Check[j]!=CheckTabl[i][j]) //

{

eq=0;

break;

};

};

if(eq==1)

{

if(Test[i]==1) Test[i]=0;

else Test[i]=1;

break;

};

};

};

case 1: //

{

for(i=0;i<8;i++)

{

for(j=0;j<7;j++)

{

TestTab[j]=Test[i*7+j];

};

short eq2;

for(j=0;j<10;j++)

{

short eq=1;

eq2=0;

for(s=0;s<7;s++)

{

if(TestTab[s]!=Tabl[j][s])

{

eq=0;

break;

};

};

if(eq==1)

{

TestCod[i]=j;

eq2=1;

break;

}

};

if(eq2==0)

{

FatalErr++;

return;

}

};

short t;

t=(TestCod[0]+TestCod[2]+TestCod[4]+TestCod[6]+3*(TestCod[1]+TestCod[3]+
TestCod[5]))%10;

if(t!=TestCod[7])

{

FatalErr++;

return;

};

for(i=0;i<8;i++)

{

if(TestCod[i]!=CodeInt[i])

{

for(j=0;j<8;j++) ErrCode[j]=TestCod[j]+48;

WarnErr++;

// info();

return;

};

};

NotFatal++;

return;

};

};

}

MOONBUG.BPR

#
———————————————————————–

!if !$d(BCB)

BCB = $(MAKEDIR)\..

!endif

# ———————————————————————

# IDE SECTION

#
———————————————————————–

# The following section of the project makefile is managed by the BCB
IDE.

# It is recommended to use the IDE to change any of the values in this

# section.

#
————————————————————————

VERSION = BCB.04.04

#
————————————————————————

PROJECT = MoonBug.exe

OBJFILES = MoonBug.obj Unit1.obj Barclass.obj Unit2.obj

RESFILES = MoonBug.res

RESDEPEN = $(RESFILES) Unit1.dfm Unit2.dfm

LIBFILES =

LIBRARIES =

SPARELIBS = VCL40.lib TEEDB40.lib Tee40.lib QRpt40.lib VclDb40.lib

PACKAGES = VCL40.bpi VCLX40.bpi VCLJPG40.bpi bcbsmp40.bpi QRPT40.bpi
VCLDB40.bpi \

ibsmp40.bpi VCLDBX40.bpi TEEUI40.bpi TEEDB40.bpi TEE40.bpi
nmfast40.bpi \

dclocx40.bpi

DEFFILE =

#
————————————————————————

PATHCPP = .;

PATHPAS = .;

PATHASM = .;

PATHRC = .;

DEBUGLIBPATH = $(BCB)\lib\debug

RELEASELIBPATH = $(BCB)\lib\release

USERDEFINES =

SYSDEFINES = _RTLDLL;NO_STRICT;USEPACKAGES

#
———————————————————————–

CFLAG1 = -I”D:\Program Files\Borland\CBuilder4\Projects”;”D:\Program
Files\Borland\CBuilder4\Projects\”;$(BCB)\include;$(BCB)\include\vcl \

-Od -Hc -H=$(BCB)\lib\vcl40.csm -w -Ve -r- -a8 -k -y -v -vi- -c -b-
-w-par \

-w-inl -Vx -tW -tWM -D$(SYSDEFINES);$(USERDEFINES)

PFLAGS = -U”D:\Program Files\Borland\CBuilder4\Projects”;”d:\program
files\borland\cbuilder4\Lib”;”d:\program
files\borland\cbuilder4\Lib\”;”D:\Program
Files\Borland\CBuilder4\Projects\”;$(BCB)\lib\obj;$(BCB)\lib;$(RELEASELI
BPATH) \

-I”D:\Program Files\Borland\CBuilder4\Projects”;”D:\Program
Files\Borland\CBuilder4\Projects\”;$(BCB)\include;$(BCB)\include\vcl \

-$YD -$W -$O- -v -JPHNE -M

RFLAGS = -i”D:\Program Files\Borland\CBuilder4\Projects”;”D:\Program
Files\Borland\CBuilder4\Projects\”;$(BCB)\include;$(BCB)\include\vcl

AFLAGS = /i”D:\Program Files\Borland\CBuilder4\Projects” \

/i”D:\Program Files\Borland\CBuilder4\Projects\” /i$(BCB)\include \

/i$(BCB)\include\vcl /mx /w2 /zd

LFLAGS = -L”D:\Program Files\Borland\CBuilder4\Projects”;”d:\program
files\borland\cbuilder4\Lib”;”d:\program
files\borland\cbuilder4\Lib\”;”D:\Program
Files\Borland\CBuilder4\Projects\”;$(BCB)\lib\obj;$(BCB)\lib;$(RELEASELI
BPATH) \

-aa -Tpe -x -Gn -v

#
————————————————————————

ALLOBJ = c0w32.obj Memmgr.Lib $(PACKAGES) sysinit.obj $(OBJFILES)

ALLRES = $(RESFILES)

ALLLIB = $(LIBFILES) $(LIBRARIES) import32.lib cp32mti.lib

#
———————————————————————–

!ifdef IDEOPTIONS

[Version Info]

IncludeVerInfo=0

AutoIncBuild=0

MajorVer=1

MinorVer=0

Release=0

Build=0

Debug=0

PreRelease=0

Special=0

Private=0

DLL=0

Locale=1049

CodePage=1251

[Version Info Keys]

CompanyName=

FileDescription=

FileVersion=1.0.0.0

InternalName=

LegalCopyright=

LegalTrademarks=

OriginalFilename=

ProductName=

ProductVersion=1.0.0.0

Comments=

[Debugging]

DebugSourceDirs=$(BCB)\source\vcl

[Parameters]

RunParams=

HostApplication=

RemoteHost=

RemotePath=

RemoteDebug=0

[Compiler]

InMemoryExe=0

ShowInfoMsgs=0

!endif

# ———————————————————————-

# MAKE SECTION

#
————————————————————————

# This section of the project file is not used by the BCB IDE. It is
for

# the benefit of building from the command-line using the MAKE utility.

#
————————————————————————

.autodepend

#
————————————————————————

!if !$d(BCC32)

BCC32 = bcc32

!endif

!if !$d(CPP32)

CPP32 = cpp32

!endif

!if !$d(DCC32)

DCC32 = dcc32

!endif

!if !$d(TASM32)

TASM32 = tasm32

!endif

!if !$d(LINKER)

LINKER = ilink32

!endif

!if !$d(BRCC32)

BRCC32 = brcc32

!endif

#
————————————————————————

!if $d(PATHCPP)

.PATH.CPP = $(PATHCPP)

.PATH.C = $(PATHCPP)

!endif

!if $d(PATHPAS)

.PATH.PAS = $(PATHPAS)

!endif

!if $d(PATHASM)

.PATH.ASM = $(PATHASM)

!endif

!if $d(PATHRC)

.PATH.RC = $(PATHRC)

!endif

#
————————————————————————

$(PROJECT): $(OBJFILES) $(RESDEPEN) $(DEFFILE)

$(BCB)\BIN\$(LINKER) @&&!

$(LFLAGS) +

$(ALLOBJ), +

$(PROJECT),, +

$(ALLLIB), +

$(DEFFILE), +

$(ALLRES)

!

#
————————————————————————

.pas.hpp:

$(BCB)\BIN\$(DCC32) $(PFLAGS) {$< }

.pas.obj:

$(BCB)\BIN\$(DCC32) $(PFLAGS) {$< }

.cpp.obj:

$(BCB)\BIN\$(BCC32) $(CFLAG1) -n$(@D) {$< }

.c.obj:

$(BCB)\BIN\$(BCC32) $(CFLAG1) -n$(@D) {$< }

.c.i:

$(BCB)\BIN\$(CPP32) $(CFLAG1) -n. {$< }

.cpp.i:

$(BCB)\BIN\$(CPP32) $(CFLAG1) -n. {$< }

.asm.obj:

$(BCB)\BIN\$(TASM32) $(AFLAGS) $<, $@

.rc.res:

$(BCB)\BIN\$(BRCC32) $(RFLAGS) -fo$@ $<

#
————————————————————————

Проект HEM-8

PROJECT1.CPP

//——————————————————————-

#include

#pragma hdrstop

USERES(“Project1.res”);

USEFORM(“Unit1.cpp”, Form1);

USEFORM(“Unit2.cpp”, AboutBox);

//——————————————————————-

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

{

try

{

Application->Initialize();

Application->CreateForm(__classid(TForm1), &Form1);

Application->CreateForm(__classid(TAboutBox),
&AboutBox);

Application->Run();

}

catch (Exception &exception)

{

Application->ShowException(&exception);

}

return 0;

}

//——————————————————————-

UNIT1.H

//———————————————————————-
—–

#ifndef Unit1H

#define Unit1H

//———————————————————————-
—–

#include

#include

#include

#include

#include

#include

#include

#include

#include

//———————————————————————-
—–

class TForm1 : public TForm

{

__published: // IDE-managed Components

TLabel *Label1;

TMaskEdit *MaskEdit1;

TSpeedButton *SpeedButton1;

TPanel *Panel1;

TImage *Image1;

TImage *Image2;

TImage *Image3;

TImage *Image4;

TImage *Image5;

TImage *Image6;

TImage *Image7;

TImage *Image8;

TImage *Image9;

TImage *Image10;

TImage *Image11;

TImage *Image12;

TImage *Image13;

TImage *Image14;

TImage *Image15;

TImage *Image16;

TImage *Image17;

TImage *Image18;

TImage *Image19;

TImage *Image20;

TImage *Image21;

TImage *Image22;

TImage *Image23;

TImage *Image24;

TImage *Image25;

TImage *Image26;

TImage *Image27;

TImage *Image28;

TImage *Image29;

TImage *Image30;

TImage *Image31;

TImage *Image32;

TImage *Image33;

TImage *Image34;

TImage *Image35;

TImage *Image36;

TImage *Image37;

TImage *Image38;

TImage *Image39;

TImage *Image40;

TImage *Image41;

TImage *Image42;

TImage *Image43;

TImage *Image44;

TImage *Image45;

TImage *Image46;

TImage *Image47;

TImage *Image48;

TImage *Image49;

TImage *Image50;

TImage *Image51;

TImage *Image52;

TImage *Image53;

TImage *Image54;

TImage *Image55;

TImage *Image56;

TImage *Image57;

TImage *Image58;

TImage *Image59;

TImage *Image60;

TImage *Image61;

TImage *Image62;

TImage *Image63;

TImage *Image64;

TImage *Image65;

TImage *Image66;

TImage *Image67;

TImage *Image68;

TImage *Image69;

TImage *Image70;

TImage *Image71;

TEdit *Edit1;

TLabel *Label2;

TLabel *Label3;

TLabel *Label4;

TLabel *Label5;

TLabel *Label6;

TLabel *Label7;

TLabel *Label8;

TLabel *Label9;

TLabel *Label10;

TMainMenu *MainMenu1;

TMenuItem *N1;

TMenuItem *N2;

TMenuItem *N3;

TMenuItem *N4;

void __fastcall SpeedButton1Click(TObject *Sender);

void __fastcall N4Click(TObject *Sender);

void __fastcall N3Click(TObject *Sender);

void __fastcall N2Click(TObject *Sender);

private: // User declarations

public: // User declarations

__fastcall TForm1(TComponent* Owner);

};

//———————————————————————-
—–

extern PACKAGE TForm1 *Form1;

//———————————————————————-
—–

#endif

UNIT1.CPP

//———————————————————————-
—–

#include

#pragma hdrstop

#include “Unit1.h”

#include “Unit2.h”

//———————————————————————-
—–

#pragma package(smart_init)

#pragma resource “*.dfm”

TForm1 *Form1;

short Tabl[10][7]=

{ {0,0,0,1,0,0,1},

{0,0,1,0,0,0,1},

{0,0,1,0,1,1,1},

{0,0,1,1,0,1,1},

{0,0,1,1,1,0,1},

{0,1,0,0,1,1,1},

{0,1,0,1,0,1,1},

{0,1,0,1,1,0,1},

{0,1,1,0,0,1,1},

{0,1,1,0,1,0,1}};

short CheckTabl[56][6]=

{

{1,1,1,1,1,1}, //*

{0,0,0,0,0,0},

{1,0,0,0,0,0},

{0,1,0,0,0,0},//1

{0,0,1,0,0,0},

{0,0,0,1,0,0},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{0,0,0,0,1,0},

{0,0,0,0,0,1},

{1,1,0,0,0,0},//2

{1,0,1,0,0,0},

{1,0,0,1,0,0},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{1,0,0,0,1,0},

{1,0,0,0,0,1},

{0,1,1,0,0,0},//3

{0,1,0,1,0,0},

{0,1,0,0,1,0},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{0,1,0,0,0,1},

{0,0,1,1,0,0},

{0,0,1,0,1,0},//4

{0,0,1,0,0,1},

{0,0,0,1,1,0},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{0,0,0,1,0,1},

{0,0,0,0,1,1},

{1,1,1,0,0,0},//5

{1,1,0,1,0,0},

{1,1,0,0,1,0},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{1,1,0,0,0,1},

{1,0,1,1,0,0},

{1,0,1,0,1,0},//6

{1,0,1,0,0,1},

{1,0,0,1,1,0},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{1,0,0,1,0,1},

{1,0,0,0,1,1},

{0,1,1,1,0,0},//7

{0,1,1,0,1,0},

{0,1,1,0,0,1},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{0,1,0,1,1,0},

{0,1,0,1,0,1},

{0,1,0,0,1,1},//8

{0,0,1,1,1,0},

{0,0,1,1,0,1},

{1,1,1,1,1,1}, //*

};

//———————————————————————-
—–

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

}

//———————————————————————-
—–

void __fastcall TForm1::SpeedButton1Click(TObject *Sender)

{

char *Buffer = new char[9]; //Creates Buffer dynamic variable

int CodeInt[8];

char MyCode[8];

char MasBit[71];

Form1->MaskEdit1->GetTextBuf(Buffer,8);

for(int i=0;i<7;i++) MyCode[i]=Buffer[i];

for(int i=0;i<7;i++) CodeInt[i]=MyCode[i]-48; CodeInt[7]=(CodeInt[0]+CodeInt[2]+CodeInt[4]+CodeInt[6]+3*(CodeInt[1]+Co deInt[3]+CodeInt[5]))%10; MyCode[7]=CodeInt[7]+48; Form1->Label3->Caption=Buffer[0];

Form1->Label4->Caption=Buffer[1];

Form1->Label5->Caption=Buffer[2];

Form1->Label6->Caption=Buffer[3];

Form1->Label7->Caption=Buffer[4];

Form1->Label8->Caption=Buffer[5];

Form1->Label9->Caption=Buffer[6];

Form1->Label10->Caption=MyCode[7];

Form1->Edit1->Text=MyCode[7];

unsigned int s; //

short TmpMas[6];

for(int i=0;i<8;i++)

{

for(int j=0;j<7;j++)

{

MasBit[i*7+j]=Tabl[(CodeInt[i])][j];

};

};

for(int i=0;i<6;i++)

{

s=0;

for(int j=0;j<56;j++) { if(CheckTabl[j][i]==0) { s+=MasBit[j]; }; }; TmpMas[i]=s%2; }; MasBit[56]=0; MasBit[57]=1; MasBit[58]=TmpMas[0]; MasBit[59]=TmpMas[1]; MasBit[60]=0; MasBit[61]=1; MasBit[62]=TmpMas[2]; MasBit[63]=TmpMas[3]; MasBit[64]=0; MasBit[65]=1; MasBit[66]=TmpMas[4]; MasBit[67]=TmpMas[5]; MasBit[68]=0; MasBit[69]=1; MasBit[70]=0; if (MasBit[0]==0) Form1->Image1->Visible=true;

else Form1->Image1->Visible=false;

if (MasBit[1]==0) Form1->Image2->Visible=true;

else Form1->Image2->Visible=false;

if (MasBit[2]==0) Form1->Image3->Visible=true;

else Form1->Image3->Visible=false;

if (MasBit[3]==0) Form1->Image4->Visible=true;

else Form1->Image4->Visible=false;

if (MasBit[4]==0) Form1->Image5->Visible=true;

else Form1->Image5->Visible=false;

if (MasBit[5]==0) Form1->Image6->Visible=true;

else Form1->Image6->Visible=false;

if (MasBit[6]==0) Form1->Image7->Visible=true;

else Form1->Image7->Visible=false;

if (MasBit[7]==0) Form1->Image8->Visible=true;

else Form1->Image8->Visible=false;

if (MasBit[8]==0) Form1->Image9->Visible=true;

else Form1->Image9->Visible=false;

if (MasBit[9]==0) Form1->Image10->Visible=true;

else Form1->Image10->Visible=false;

if (MasBit[10]==0) Form1->Image11->Visible=true;

else Form1->Image11->Visible=false;

if (MasBit[11]==0) Form1->Image12->Visible=true;

else Form1->Image12->Visible=false;

if (MasBit[12]==0) Form1->Image13->Visible=true;

else Form1->Image13->Visible=false;

if (MasBit[13]==0) Form1->Image14->Visible=true;

else Form1->Image14->Visible=false;

if (MasBit[14]==0) Form1->Image15->Visible=true;

else Form1->Image15->Visible=false;

if (MasBit[15]==0) Form1->Image16->Visible=true;

else Form1->Image16->Visible=false;

if (MasBit[16]==0) Form1->Image17->Visible=true;

else Form1->Image17->Visible=false;

if (MasBit[17]==0) Form1->Image18->Visible=true;

else Form1->Image18->Visible=false;

if (MasBit[18]==0) Form1->Image19->Visible=true;

else Form1->Image19->Visible=false;

if (MasBit[19]==0) Form1->Image20->Visible=true;

else Form1->Image20->Visible=false;

if (MasBit[20]==0) Form1->Image21->Visible=true;

else Form1->Image21->Visible=false;

if (MasBit[21]==0) Form1->Image22->Visible=true;

else Form1->Image22->Visible=false;

if (MasBit[22]==0) Form1->Image23->Visible=true;

else Form1->Image23->Visible=false;

if (MasBit[23]==0) Form1->Image24->Visible=true;

else Form1->Image24->Visible=false;

if (MasBit[24]==0) Form1->Image25->Visible=true;

else Form1->Image25->Visible=false;

if (MasBit[25]==0) Form1->Image26->Visible=true;

else Form1->Image26->Visible=false;

if (MasBit[26]==0) Form1->Image27->Visible=true;

else Form1->Image27->Visible=false;

if (MasBit[27]==0) Form1->Image28->Visible=true;

else Form1->Image28->Visible=false;

if (MasBit[28]==0) Form1->Image29->Visible=true;

else Form1->Image29->Visible=false;

if (MasBit[29]==0) Form1->Image30->Visible=true;

else Form1->Image30->Visible=false;

if (MasBit[30]==0) Form1->Image31->Visible=true;

else Form1->Image31->Visible=false;

if (MasBit[31]==0) Form1->Image32->Visible=true;

else Form1->Image32->Visible=false;

if (MasBit[32]==0) Form1->Image33->Visible=true;

else Form1->Image33->Visible=false;

if (MasBit[33]==0) Form1->Image34->Visible=true;

else Form1->Image34->Visible=false;

if (MasBit[34]==0) Form1->Image35->Visible=true;

else Form1->Image35->Visible=false;

if (MasBit[35]==0) Form1->Image36->Visible=true;

else Form1->Image36->Visible=false;

if (MasBit[36]==0) Form1->Image37->Visible=true;

else Form1->Image37->Visible=false;

if (MasBit[37]==0) Form1->Image38->Visible=true;

else Form1->Image38->Visible=false;

if (MasBit[38]==0) Form1->Image39->Visible=true;

else Form1->Image39->Visible=false;

if (MasBit[39]==0) Form1->Image40->Visible=true;

else Form1->Image40->Visible=false;

if (MasBit[40]==0) Form1->Image41->Visible=true;

else Form1->Image41->Visible=false;

if (MasBit[41]==0) Form1->Image42->Visible=true;

else Form1->Image42->Visible=false;

if (MasBit[42]==0) Form1->Image43->Visible=true;

else Form1->Image43->Visible=false;

if (MasBit[43]==0) Form1->Image44->Visible=true;

else Form1->Image44->Visible=false;

if (MasBit[44]==0) Form1->Image45->Visible=true;

else Form1->Image45->Visible=false;

if (MasBit[45]==0) Form1->Image46->Visible=true;

else Form1->Image46->Visible=false;

if (MasBit[46]==0) Form1->Image47->Visible=true;

else Form1->Image47->Visible=false;

if (MasBit[47]==0) Form1->Image48->Visible=true;

else Form1->Image48->Visible=false;

if (MasBit[48]==0) Form1->Image49->Visible=true;

else Form1->Image49->Visible=false;

if (MasBit[49]==0) Form1->Image50->Visible=true;

else Form1->Image50->Visible=false;

if (MasBit[50]==0) Form1->Image51->Visible=true;

else Form1->Image51->Visible=false;

if (MasBit[51]==0) Form1->Image52->Visible=true;

else Form1->Image52->Visible=false;

if (MasBit[52]==0) Form1->Image53->Visible=true;

else Form1->Image53->Visible=false;

if (MasBit[53]==0) Form1->Image54->Visible=true;

else Form1->Image54->Visible=false;

if (MasBit[54]==0) Form1->Image55->Visible=true;

else Form1->Image55->Visible=false;

if (MasBit[55]==0) Form1->Image56->Visible=true;

else Form1->Image56->Visible=false;

if (MasBit[56]==0) Form1->Image57->Visible=true;

else Form1->Image57->Visible=false;

if (MasBit[57]==0) Form1->Image58->Visible=true;

else Form1->Image58->Visible=false;

if (MasBit[58]==0) Form1->Image59->Visible=true;

else Form1->Image59->Visible=false;

if (MasBit[59]==0) Form1->Image60->Visible=true;

else Form1->Image60->Visible=false;

if (MasBit[60]==0) Form1->Image61->Visible=true;

else Form1->Image61->Visible=false;

if (MasBit[61]==0) Form1->Image62->Visible=true;

else Form1->Image62->Visible=false;

if (MasBit[62]==0) Form1->Image63->Visible=true;

else Form1->Image63->Visible=false;

if (MasBit[63]==0) Form1->Image64->Visible=true;

else Form1->Image64->Visible=false;

if (MasBit[64]==0) Form1->Image65->Visible=true;

else Form1->Image65->Visible=false;

if (MasBit[65]==0) Form1->Image66->Visible=true;

else Form1->Image66->Visible=false;

if (MasBit[66]==0) Form1->Image67->Visible=true;

else Form1->Image67->Visible=false;

if (MasBit[67]==0) Form1->Image68->Visible=true;

else Form1->Image68->Visible=false;

if (MasBit[68]==0) Form1->Image69->Visible=true;

else Form1->Image69->Visible=false;

if (MasBit[69]==0) Form1->Image70->Visible=true;

else Form1->Image70->Visible=false;

if (MasBit[70]==0) Form1->Image71->Visible=true;

else Form1->Image71->Visible=false;

}

//———————————————————————-
—–

void __fastcall TForm1::N4Click(TObject *Sender)

{

Form1->SpeedButton1->Click();

}

//———————————————————————-
—–

void __fastcall TForm1::N3Click(TObject *Sender)

{

Close();

}

//———————————————————————-
—–

void __fastcall TForm1::N2Click(TObject *Sender)

{

AboutBox->ShowModal();

}

//———————————————————————-
—–

UNIT2.H

//———————————————————————-
——

#ifndef Unit2H

#define Unit2H

//———————————————————————-
——

#include <vcl\System.hpp>

#include <vcl\Windows.hpp>

#include <vcl\SysUtils.hpp>

#include <vcl\Classes.hpp>

#include <vcl\Graphics.hpp>

#include <vcl\Forms.hpp>

#include <vcl\Controls.hpp>

#include <vcl\StdCtrls.hpp>

#include <vcl\Buttons.hpp>

#include <vcl\ExtCtrls.hpp>

//———————————————————————-
——

class TAboutBox : public TForm

{

__published:

TPanel *Panel1;

TImage *ProgramIcon;

TLabel *ProductName;

TLabel *Version;

TLabel *Copyright;

TLabel *Comments;

TButton *OKButton;

private:

public:

virtual __fastcall TAboutBox(TComponent* AOwner);

};

//———————————————————————-
——

extern PACKAGE TAboutBox *AboutBox;

//———————————————————————-
——

#endif

UNIT2.CPP

//———————————————————————

#include

#pragma hdrstop

#include “Unit2.h”

//———————————————————————

#pragma resource “*.dfm”

TAboutBox *AboutBox;

//———————————————————————

__fastcall TAboutBox::TAboutBox(TComponent* AOwner)

: TForm(AOwner)

{

}

//———————————————————————

PROJECT1.BPR

# ——————————————————————-

!if !$d(BCB)

BCB = $(MAKEDIR)\..

!endif

# ——————————————————————-

# IDE SECTION

# ——————————————————————-

# The following section of the project makefile is managed by the BCB
IDE.

# It is recommended to use the IDE to change any of the values in this

# section.

# ——————————————————————-

VERSION = BCB.04.04

#
————————————————————————

PROJECT = Project1.exe

OBJFILES = Project1.obj Unit1.obj Unit2.obj

RESFILES = Project1.res

RESDEPEN = $(RESFILES) Unit1.dfm Unit2.dfm

LIBFILES =

LIBRARIES =

SPARELIBS = VCL40.lib

PACKAGES = VCL40.bpi VCLX40.bpi VCLJPG40.bpi bcbsmp40.bpi QRPT40.bpi
VCLDB40.bpi \

ibsmp40.bpi VCLDBX40.bpi TEEUI40.bpi TEEDB40.bpi TEE40.bpi
nmfast40.bpi \

dclocx40.bpi

DEFFILE =

#
————————————————————————

PATHCPP = .;

PATHPAS = .;

PATHASM = .;

PATHRC = .;

DEBUGLIBPATH = $(BCB)\lib\debug

RELEASELIBPATH = $(BCB)\lib\release

USERDEFINES =

SYSDEFINES = _RTLDLL;NO_STRICT;USEPACKAGES

#
————————————————————————

CFLAG1 = -I”D:\Program
Files\Borland\CBuilder4\Projects”;$(BCB)\include;$(BCB)\include\vcl \

-Od -Hc -H=$(BCB)\lib\vcl40.csm -w -Ve -r- -a8 -k -y -v -vi- -c -b-
-w-par \

-w-inl -Vx -tW -tWM -D$(SYSDEFINES);$(USERDEFINES)

PFLAGS = -U”D:\Program
Files\Borland\CBuilder4\Projects”;$(BCB)\lib\obj;$(BCB)\lib;$(RELEASELIB
PATH) \

-I”D:\Program
Files\Borland\CBuilder4\Projects”;$(BCB)\include;$(BCB)\include\vcl \

-$YD -$W -$O- -v -JPHNE -M

RFLAGS = -i”D:\Program
Files\Borland\CBuilder4\Projects”;$(BCB)\include;$(BCB)\include\vcl

AFLAGS = /i$(BCB)\include /i$(BCB)\include\vcl /mx /w2 /zd

LFLAGS = -L”D:\Program
Files\Borland\CBuilder4\Projects”;$(BCB)\lib\obj;$(BCB)\lib;$(RELEASELIB
PATH) \

-aa -Tpe -x -Gn -v

#
————————————————————————

ALLOBJ = c0w32.obj Memmgr.Lib $(PACKAGES) sysinit.obj $(OBJFILES)

ALLRES = $(RESFILES)

ALLLIB = $(LIBFILES) $(LIBRARIES) import32.lib cp32mti.lib

#
————————————————————————

!ifdef IDEOPTIONS

[Version Info]

IncludeVerInfo=0

AutoIncBuild=0

MajorVer=1

MinorVer=0

Release=0

Build=0

Debug=0

PreRelease=0

Special=0

Private=0

DLL=0

Locale=1049

CodePage=1251

[Version Info Keys]

CompanyName=

FileDescription=

FileVersion=1.0.0.0

InternalName=

LegalCopyright=

LegalTrademarks=

OriginalFilename=

ProductName=

ProductVersion=1.0.0.0

Comments=

[Debugging]

DebugSourceDirs=$(BCB)\source\vcl

[Parameters]

RunParams=

HostApplication=

RemoteHost=

RemotePath=

RemoteDebug=0

[Compiler]

InMemoryExe=0

ShowInfoMsgs=0

!endif

#
————————————————————————

# MAKE SECTION

#
————————————————————————

# This section of the project file is not used by the BCB IDE. It is
for

# the benefit of building from the command-line using the MAKE utility.

#
————————————————————————

.autodepend

#
————————————————————————

!if !$d(BCC32)

BCC32 = bcc32

!endif

!if !$d(CPP32)

CPP32 = cpp32

!endif

!if !$d(DCC32)

DCC32 = dcc32

!endif

!if !$d(TASM32)

TASM32 = tasm32

!endif

!if !$d(LINKER)

LINKER = ilink32

!endif

!if !$d(BRCC32)

BRCC32 = brcc32

!endif

#
————————————————————————

!if $d(PATHCPP)

.PATH.CPP = $(PATHCPP)

.PATH.C = $(PATHCPP)

!endif

!if $d(PATHPAS)

.PATH.PAS = $(PATHPAS)

!endif

!if $d(PATHASM)

.PATH.ASM = $(PATHASM)

!endif

!if $d(PATHRC)

.PATH.RC = $(PATHRC)

!endif

#
————————————————————————

$(PROJECT): $(OBJFILES) $(RESDEPEN) $(DEFFILE)

$(BCB)\BIN\$(LINKER) @&&!

$(LFLAGS) +

$(ALLOBJ), +

$(PROJECT),, +

$(ALLLIB), +

$(DEFFILE), +

$(ALLRES)

!

#
————————————————————————

.pas.hpp:

$(BCB)\BIN\$(DCC32) $(PFLAGS) {$< }

.pas.obj:

$(BCB)\BIN\$(DCC32) $(PFLAGS) {$< }

.cpp.obj:

$(BCB)\BIN\$(BCC32) $(CFLAG1) -n$(@D) {$< }

.c.obj:

$(BCB)\BIN\$(BCC32) $(CFLAG1) -n$(@D) {$< }

.c.i:

$(BCB)\BIN\$(CPP32) $(CFLAG1) -n. {$< }

.cpp.i:

$(BCB)\BIN\$(CPP32) $(CFLAG1) -n. {$< }

.asm.obj:

$(BCB)\BIN???????????????????††?????????????????????????????????????????
???????????????????

Проект KORAN(OLDKORAN)

KORAN.H

#define N 1

unsigned stop;

char cCase=’1′;

char cvar;

char pstr1[8];

char* pStr=”koran.krn “;

int iFile;

int ii;

void titul();

KORANCLASS.H

class BarCode {

private:

unsigned char pcode[8];

unsigned char textdata[25];

char cod[8];

char flag;

char f1;

char f2;

char masbit[71];

char errbit[71];

unsigned char ecode[8];

double err;

double ferr;

double nferr;

double warning;

public:

void bitcode();

void checksum();

void init(char*,char);

void getmytime();

void save(char*,BarCode*);

void read(char*,BarCode*);

short next();

void test();

void info();

void gen_error();

};

KORAN.CPP

#include

#include

#include

#include

#include

#include

#include

#include

#include “koran\koran.h”

#include “koran\krnclass.h”

void main()

{

BarCode bcode;//= new BarCode;;

do

{

titul();

bcode.getmytime();

cout<<“1. Beginn prufung\n”;

cout<<“2. Fortsetzen prufung\n\n”;

cout<<” ? “;

cCase=getch();

} while((cCase!=’1′)&(cCase!=’2’));

switch (cCase)

{

case ‘1’:

{

titul();

cout<<“Einfurst der Filename(*.krn): [ ]\b\b\b\b\b\b\b\b\b”; cin>>pStr;

strcat(pStr,”.krn”);

titul();

cout<<“Einfurst anfangs kode: [ ]\b\b\b\b\b\b\b\b”; cin>>pstr1;

do

{

cout<<“\nEinfurst der Anzahl fehler(1/2): [ ]\b\b”; cin>>cvar;

} while ((cvar!=’2′)&(cvar!=’1′));

bcode.init(pstr1,cvar);

bcode.save(pStr,&bcode);

break;

}; // case ‘1’

case ‘2’:

{

titul();

cout<<“Einfurst der Filename(*.krn): [ ]\b\b\b\b\b\b\b\b\b”; cin>>pStr;

strcat(pStr,”.krn”);

bcode.read(pStr,&bcode);

break;

}

}; // end of switch-case

int n=0;

int commandquit;

do

{

bcode.checksum();

bcode.bitcode();

bcode.gen_error();

bcode.info();

if(n++==100)

{

bcode.save(pStr,&bcode);

n=0;

};

if(_bios_keybrd(_KEYBRD_READY)) commandquit=getch();

stop=bcode.next(); // +

} while ((stop==1)&(commandquit!=’q’));

bcode.save(pStr,&bcode);

return;

}

KORAN_PR.CPP

#include

#include

#include

#include

#include “koran\krnclass.h”

#include

#include

short tabl[10][7]=

{ {0,0,0,1,0,0,1},

{0,0,1,0,0,0,1},

{0,0,1,0,1,1,1},

{0,0,1,1,0,1,1},

{0,0,1,1,1,0,1},

{0,1,0,0,1,1,1},

{0,1,0,1,0,1,1},

{0,1,0,1,1,0,1},

{0,1,1,0,0,1,1},

{0,1,1,0,1,0,1}};

short checktabl[56][6]=

{

{1,1,1,1,1,1}, //*

{0,0,0,0,0,0},

{1,0,0,0,0,0},

{0,1,0,0,0,0},//1

{0,0,1,0,0,0},

{0,0,0,1,0,0},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{0,0,0,0,1,0},

{0,0,0,0,0,1},

{1,1,0,0,0,0},//2

{1,0,1,0,0,0},

{1,0,0,1,0,0},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{1,0,0,0,1,0},

{1,0,0,0,0,1},

{0,1,1,0,0,0},//3

{0,1,0,1,0,0},

{0,1,0,0,1,0},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{0,1,0,0,0,1},

{0,0,1,1,0,0},

{0,0,1,0,1,0},//4

{0,0,1,0,0,1},

{0,0,0,1,1,0},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{0,0,0,1,0,1},

{0,0,0,0,1,1},

{1,1,1,0,0,0},//5

{1,1,0,1,0,0},

{1,1,0,0,1,0},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{1,1,0,0,0,1},

{1,0,1,1,0,0},

{1,0,1,0,1,0},//6

{1,0,1,0,0,1},

{1,0,0,1,1,0},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{1,0,0,1,0,1},

{1,0,0,0,1,1},

{0,1,1,1,0,0},//7

{0,1,1,0,1,0},

{0,1,1,0,0,1},

{1,1,1,1,1,1}, //*

{1,1,1,1,1,1}, //*

{0,1,0,1,1,0},

{0,1,0,1,0,1},

{0,1,0,0,1,1},//8

{0,0,1,1,1,0},

{0,0,1,1,0,1},

{1,1,1,1,1,1}, //*

};

void titul()

{

clrscr();

cout<< “Der Diplomprojekt v.1.2 ‘Koran’ Mishel Kozak\n\n”;

}

//———————————————-

//

// Methode fur Klasse

//

//———————————————-

void BarCode::init(char* mas,char fl)

{

int i;

flag=fl;

f1=1;

f2=2;

for(i=0;i<7;i++)

{cod[i]=mas[i]-48;

pcode[i]=mas[i];

};

cod[7]=0;

err=0;

ferr=0;

nferr=0;

warning=0;

}

//———————————————-

void BarCode::getmytime()

{

struct tm mytm;

struct time tt;

struct date dd;

char* sss;

gettime(&tt);

getdate(&dd);

mytm.tm_sec=0;

mytm.tm_wday=0;

mytm.tm_year=0;

mytm.tm_isdst=0;

mytm.tm_min=tt.ti_min;

mytm.tm_hour=tt.ti_hour;

mytm.tm_mday=dd.da_day;

mytm.tm_mon=dd.da_mon-1;

mytm.tm_year=dd.da_year-1900;

int ii,jj;

sss=asctime(&mytm);

for(ii=3,jj=0;jj<25;ii++,jj++)

textdata[jj]=sss[ii];

// textdata[jj++]=’\n’;

// textdata[jj++]=’\0′;

}

//———————————————-

void BarCode::save(char* pstr,BarCode* bco)

{

ofstream rootf(pstr,ios::binary);

if(rootf)

{

rootf.write((char*)bco,sizeof(*bco));

// rootf.write((char*)&bcode,sizeof(bcode));

}

else

{

cout<<“Error open file: “<<pstr;

}

}

//———————————————-

void BarCode::read(char* pstr,BarCode* bco)

{

ifstream rootf(pstr,ios::binary);

if(rootf)

{

rootf.read((char*)bco,sizeof(*bco));

}

else

{

cout<<“Error open file: “<<pstr;

}

}

//———————————————-

void BarCode::checksum()

{

cod[7]=(cod[0]+cod[2]+cod[4]+cod[6]+3*(cod[1]+cod[3]+cod[5]))%10;

pcode[7]=cod[7]+48;

// titul();

// cout<<“\n Code: “<<pcode[0]<<” “<<pcode[1]<<” “<<pcode[2]<<”
“<<pcode[3]<<” “<<pcode[4];

// cout<<” “<<pcode[5]<<” “<<pcode[6]<<” “<<pcode[7]<<“\n\n”;

}

//———————————————-

short BarCode::next()

{

if(cod[6]!=9) { cod[6]++; pcode[6]++;}

else

{

if(cod[5]!=9) { cod[5]++; pcode[5]++; }

else

{

if(cod[4]!=9) {cod[4]++;pcode[4]++;}

else

{

if(cod[3]!=9) {cod[3]++;pcode[3]++;}

else

{

if(cod[2]!=9) {cod[2]++;pcode[2]++;}

else

{

if(cod[1]!=9) {cod[1]++;pcode[1]++;}

else

{

if(cod[0]!=9) {cod[0]++;pcode[0]++;}

else return(0);

cod[1]=0;

pcode[1]=’0′;

};

cod[2]=0;

pcode[2]=’0′;

};

cod[3]=0;

pcode[3]=’0′;

};

cod[4]=0;

pcode[4]=’0′;

};

cod[5]=0;

pcode[5]=’0′;

};

cod[6]=0;

pcode[6]=’0′;

};

return(1);

}

//———————————————-

void BarCode::info()

{

{

titul();

getmytime();

cout<<” “<<textdata;

cout<<“\n Code: “<<pcode[0]<<” “<<pcode[1]<<” “<<pcode[2]<<”
“<<pcode[3]<<” “<<pcode[4];

cout<<” “<<pcode[5]<<” “<<pcode[6]<<” “<<pcode[7]<<“\n\n”;

cout<<“\n Code: “<<ecode[0]<<” “<<ecode[1]<<” “<<ecode[2]<<”
“<<ecode[3]<<” “<<ecode[4];

cout<<” “<<ecode[5]<<” “<<ecode[6]<<” “<<ecode[7]<<“\n\n”;

cout<<“\n Type error: “<<flag;

int i;

cout<<“\n – 1- 1- 1- 1- 1- 1- 1-
1-1 -1 -1 -1-\n “;

cout<<“\n Real”;

for(i=0;i<71;i++)

{

char ch;

if(masbit[i]==0) ch=219;

else ch=0;

cout<<ch;

};

cout<<“\nerror”;

for(i=0;i<71;i++)

{

char ch;

if(errbit[i]==0) ch=219;

else ch=0;

cout<<ch;

};

cout<<“\n\n Total error: “<<err;

cout<<“\n = fatal error: “<<ferr<<” “<<ferr/(err/100)<<“%”;

cout<<“\n = corectly error: “<<nferr<<” “<<nferr/(err/100)<<“%”;

cout<<“\n = warning error: “<<warning<<”
“<<warning/(err/100)<<“%”;

cout<<“\n\n\n\n For exit press ‘q’… “;

}

}

//———————————————-

void BarCode::bitcode()

{

unsigned int i,j,s;

short tmpmas[6];

for(i=0;i<8;i++)

{

for(j=0;j<7;j++)

{

masbit[i*7+j]=tabl[(cod[i])][j];

};

};

for(i=0;i<6;i++)

{

s=0;

for(j=0;j<56;j++)

{

if(checktabl[j][i]==0)

{

s+=masbit[j];

};

};

tmpmas[i]=s%2;

};

masbit[56]=0;

masbit[57]=1;

masbit[58]=tmpmas[0];

masbit[59]=tmpmas[1];

masbit[60]=0;

masbit[61]=1;

masbit[62]=tmpmas[2];

masbit[63]=tmpmas[3];

masbit[64]=0;

masbit[65]=1;

masbit[66]=tmpmas[4];

masbit[67]=tmpmas[5];

masbit[68]=0;

masbit[69]=1;

masbit[70]=0;

for(i=0;i<71;i++) errbit[i]=masbit[i];

}

//——————————————

void BarCode::gen_error()

{

if(flag==’1′)

{

f1=1;

do

{

if(errbit[f1]==0) errbit[f1]=1;

else if(errbit[f1]==1) errbit[f1]=0;

test();

if(errbit[f1]==0) errbit[f1]=1;

else if(errbit[f1]==1) errbit[f1]=0;

f1++;

} while(f1<72);

};

if(flag==’2’)

{

f1=1;

do

{

f2=f1+1;

do

{

if(errbit[f1]==0) errbit[f1]=1;

else if(errbit[f1]==1) errbit[f1]=0;

if(errbit[f2]==0) errbit[f2]=1;

else if(errbit[f2]==1) errbit[f2]=0;

test();

if(errbit[f1]==0) errbit[f1]=1;

else if(errbit[f1]==1) errbit[f1]=0;

if(errbit[f2]==0) errbit[f2]=1;

else if(errbit[f2]==1) errbit[f2]=0;

f2++;

} while(f2<72);

f1++;

} while(f1<71);

};

}

//———————————————-

void BarCode::test()

{

short tmpmas[6];

short i,j,s;

short check[6]={1,1,1,1,1,1};

char testcod[8];

char test[71];

char testtab[7];

err++;

for(i=0;i<71;i++)

test[i]=errbit[i];

for(i=0;i<8;i++)

{

test[i*7]=0;

test[i*7+6]=1;

};

test[56]=0;

test[57]=1;

test[60]=0;

test[61]=1;

test[64]=0;

test[65]=1;

test[68]=0;

test[69]=1;

test[70]=0;

for(i=0;i<6;i++)

{

s=0;

for(j=0;j<56;j++)

{

if(checktabl[j][i]==0)

{

s+=test[j];

};

};

tmpmas[i]=s%2;

};

for(j=0;j<3;j++)

{

if(tmpmas[j*2]!=test[58+j*4]) check[j*2]=0;

if(tmpmas[j*2+1]!=test[59+j*4]) check[j*2+1]=0;

};

short n=0;

for(i=0;i<6;i++) { if(check[i]==0) { n++; }; }; if(n>1) n=0;

else n=1;

switch (n)

{

case 0://якщо контрольна сума не спiвпадае

{

for(i=0;i<56;i++)

{

short eq=1;

for(j=0;j<6;j++)

{

if(check[j]!=checktabl[i][j])

{

eq=0;

break;

};

};

if(eq==1)

{

if(test[i]==1) test[i]=0;

else test[i]=1;

break;

};

};

};

case 1: //якщо контрольна сума спiвпадае

{

for(i=0;i<8;i++)

{

for(j=0;j<7;j++)

{

testtab[j]=test[i*7+j];

};

short eq2;

for(j=0;j<10;j++)

{

short eq=1;

eq2=0;

for(s=0;s<7;s++)

{

if(testtab[s]!=tabl[j][s])

{

eq=0;

break;

};

};

if(eq==1)

{

testcod[i]=j;

eq2=1;

break;

}

};

if(eq2==0)

{

ferr++;

return;

}

};

short t;

t=(testcod[0]+testcod[2]+testcod[4]+testcod[6]+3*(testcod[1]+testcod[3]+
testcod[5]))%10;

if(t!=testcod[7])

{

ferr++;

return;

};

for(i=0;i<8;i++)

{

if(testcod[i]!=cod[i])

{

for(j=0;j<8;j++) ecode[j]=testcod[j]+48;

warning++;

info();

return;

};

};

nferr++;

return;

};

};

}

Висновки

В ході виконання цієї дипломної роботи, було розглянуто принципи
побудови штрихових кодів, було розглянуто деякі з найвживаніших типів
штрихкодів, та створено суттєво новий тип штрихового коду HEM-8. На
основі проведеної роботи можна як підсумок привести слідуючі висновки:

1. Надлишковість при передачі інформації не завжди негативне явище. Її
можна використовувати для збільшення надійності передачі інформації. З
певними обумовленнями можна стверджувати, що при збільшенні
надлишковості коду, збільшується надійність коду, стійкість його до
помилок.

2. При виборі того чи іншого типу штрихового коду необхідно вирішити
питання про співвідношення неохідної надійності коду(стійкості його до
помилок) до надлишковості коду. Для тієї чи іншої задачі це
співвідношення може суттєво різнитися. В одних випадках більш важливим
фактором є надійність коду, а в інших його компактність.

3. Все сказане в попередньому пінкті стосується не тільки штрихових
кодів, а і будь-якого іншого способу дискретної передачі інформації.

4. Штриховий код є зручний спосіб автоматизації вводу інформації в
найрізноманітніших сферах людської діяльності. В кожній конкретній сфері
до штрихового коду ставляться свої, в чомусь унікальні вимоги, в
наслідок чого, зараз в світі створено велику кількість
найрізноманітніших типів штрихових кодів, а також продовжується
створення все нових і нових типів.

Але головним підсумком цієї дипломної роботи є створений новий тип
штрихового коду НЕМ-8, штрихкод який не має аналогів серед сотень інших
типів кодів, і ефективність якого вже було продемонстровано. Розробка та
дослідження НЕМ-подібних кодів не обмежується цією дипломною роботою і
буде продовжуватись й надалі, з метою створення та вдосконалення
ефективних типів штрихових кодів.

ДЖЕРЕЛА

1. Шинон К. Работы по теории информации и кибернетике / Пер. с англ.
под ред. Добрушина Р.Л.,Лупанова О.Б. -М.: Издательство иностранной
литературы, 1963. 830 с.

2. Котов П.А. Повышение достоверности передачи цифровой информации.
-М.: Связь, 1966. 184 с.

3. Словарь по кибернетике / Справочное издание под редакцией Михалевича
В.С. -К.: Главная редакция Украинской Советской Энциклопедии имени
М.П.Бажана, 1989. 752 с.

4. Фейсон Т. Объектно-ориентированное програмирование на Borland C++
4.5. -К.: Диалектика, 1996. -544 с., ил.

5. Understanding ActivX and OLE. David Chapell, Microsoft Press, 1996.

6. How to crack / A Tutorial by +ORC, [email protected]

7. Cracking as an art, [Barcodes][Instant Access] / Lesson C(1).
[email protected]

8. Handbuch zum barcode-lesegerat / ABP-Programierhandbuch fur
Einbauscanner.

9. Barcodes FAQ. : www.azalea.com

10. Barcodes. : www.incom.ru/barcodes/s1.html

PAGE 1

PAGE 38

Нашли опечатку? Выделите и нажмите CTRL+Enter

Похожие документы
Обсуждение

Ответить

Курсовые, Дипломы, Рефераты на заказ в кратчайшие сроки
Заказать реферат!
UkrReferat.com. Всі права захищені. 2000-2020