Комментарии 18
А почему для записи длины не использовали унарный код? Так можно вместить от 0 до 7 знаков.
0XXXXXXX - 7 знаков
10XXXXXX - 6 знаков
...
111110XX - 2 знака
1111110X - 1 знак
11111110 - 0 знаков
(X - это точка или тире. Число знаков = 7-число единиц перед первым нулём)
А если учесть, что 7-знаковый код всего один, можно один бит вообще зарезервировать под индикатор служебного кода. Так все 6-знаки кодируются вашим способом, а если служебный бит "1", то все остальные кодируют 7-битовый служебный код.
Среди них можно разместить много полезного:
- три выбивающихся кода (7, 8 и 9-знак),
- управляющий сигнал на включение/выключение лентопротяжного механизма,
- включение/выключение передатчика...
- можно научить вашу функцию помнить состояние и реализовать Escape последовательности, что даст возможность объединять любые N-графы без пауз, однако кодировка перестаёт при этом быть однобайтной для таких случаев и напоминает UTF-8
1-0XXXXXX - 6 знаков
1-10XXXXX - 5 знаков
...
1-111110X - 1 знак
1-1111110 - 0 знаков
0-YYYYYYY - все 7-битные служебные коды:
0-0000000 - символ начала escape последовательности
0-1000111 - $ [SX]
0-1001000 - [HH]
0-1000101 - [SOS]
0-0ZZZZZZ - количество последующих знаков без разбиения N-граф
тут вообще что угодно можно намутить
111110X1 - 1 знак
...
0XXXXXX1 - 6 знаков
0XXXXXX0 111110X1 - 7 знаков
...
0XXXXXX0 0XXXXXX1 - 12 знаков
О, да, так ещё лучше. Если не нужны служебные управляющие коды, то вообще идеально
Или же можно использовать комбинацию 111111YY, если хватит четырёх служебных кодов.
Или даже так, с двумя специальными комбинацияами:
1111110X - 1 знак
...
0XXXXXXX - 7 знаков
11111110 - Error/correction [HH]
11111111 - [SOS]
Служебных кодов не будет, но все стандартные символы умещаются в один байт, требуется только обработка двух специальных случаев.
00000000 — [HH] + пауза длительностью 2 интервала
00001001 — [$] + пауза длительностью 2 интервала
10XXXXXX — [6 знаков] + пауза длительностью 2 интервала
…
111110XX — [2 знака] + пауза длительностью 2 интервала
1111110X — [1 знак] + пауза длительностью 2 интервала
11111110 — только пауза длительностью 4 интервала
11111111 — [SOS] + пауза длительностью 2 интервала
начальный счетчик цикла равен 8
далее пошаговый сдвиг влево через Carry флаг
комбинации 00000000, 11111111, 11111110 обрабатываются вне основного цикла
Вы придумали свой алгоритм, как в байте указать точки и тире в виде единиц и нулей, но из-за разного количества знаков, вам в тот же байт нужно также прописать это длину. В результате выходит сложный и неудобный алгоритм, который может не сработать на всех имеющихся знаках.
При этом всего, у вас 67 различных сигналов, а в байт можно запихнуть 256 без вообще каких-либо алгоритмов, банальной таблицей соответствий.
Какая стоит цель данного алгоритма? Сэкономить 100 байт кода? Но он получается не универсален для разных языков.
И да, выше привели алгоритм попроще, за исключением что нужно сделать отдельный сигнал для девятисимвольного SOS
Тем более, что SOS это три отдельных буквы: S, O и, неожиданно, снова S. Нет никакой объективной необходимости создавать отдельный сигнал вместо последовательной передачи составляющих его отдельных букв.
Также в морзянке были отдельные «буквы» для «конец связи» и «ошибка передачи»
Конец связи — SK, часто действительно передаваемые слитно, а не как положено отдельными буквами.
А тут неуникальные строчки — это так задумано?
".-.-." : "+", # Plus sign [+]
".-.-." : ("[AR]", "digraph - New Page Signal"),
".--.-." : " Ъъ",
".--.-." : "@", # [AC] digraph - At Sign [@]
У меня, наверное, профдеформация, но в реальной практике использования телеграфа нужны только буквы стандартной латиницы, цифры, дробь и единственный знак вопроса. Даже точка и запятая редкость. Это не значит, что они не нужны в принципе, но значит, что с поправкой на специфику использования (которая мне не вполне понятна из статьи) малоиспользуемые знаки может быть можно исключить, если этим достигается упрощение программы или устройства, на котором эта программа будет работать.
8-разрядный код Морзе