Asn Stripping Board

👉🏻👉🏻👉🏻 ALL INFORMATION CLICK HERE 👈🏻👈🏻👈🏻
Удаленная работа для IT-специалистов
Приведённый ниже текст является на самом деле первыми двумя главами моей статьи "ASN.1 простыми словами". Так как сама статья достаточно большая по меркам Хабра я решил сначала проверить являются ли знания по кодированию простых типов востребованными на этом ресурсе. В случае положительной реакции аудитории я продолжу публикацию всех остальных глав.
Уже на протяжение достаточно большого периода мне приходится иметь дело с ASN.1. Мне посчастливилось работать как в сфере создания криптографических программ, так и в сфере телекоммуникаций. И в той, и в другой сфере изначально крайне активно и повсеместно используется стандарт ASN.1.
Однако и в процессе создания программ криптографической направленности, и в процессе создания программ для телекоммуникационной отрасли я постоянно встречался с одним и тем же мнением — ASN.1 это сложный и не понятный формат, а следовательно для кодирования / декодирования лучше применять сторонние компиляторы (а иногда даже другие стандарты кодирования передаваемой информации).
Одной из причин по которой сложилась ситуация, когда подавляющее большинство разработчиков программ считают стандарт ASN.1 сложным, это отсутствие книг по данному вопросу. Да, не смотря на почтенный возраст данного стандарта, множество свободно распространяемых компиляторов и различных статей, всё ещё крайне мало книг (или даже статей в Интернете) где бы простым и понятным языком, с большим количеством примеров, прояснялись вопросы кодирования простых типов ASN.1.
В большинстве пособий и книг по ASN.1 изучение кодирования начинается с простейших, не сложных, типов и заканчивается наисложнейшими. В этой статье порядок будет строго противоположный — читателю сначала будет предложено изучить кодирование сложных типов, и только потом постепенно перейдём к изучению простейших. Это позволит однажды усвоив методы кодирования для сложного типа просто и быстро понять методику кодирования более простого.
Первично всё же необходимо пояснить некоторые основы кодирования в формате ASN.1.
Для начала поясним для чего же создавался этот стандарт. В мире существует множество различных компьютеров. И кроме того существует множество стандартов представления данных в этих компьютерах. ASN.1 создавался как некий общий стандарт, позволяющий описывать произвольную информацию, которая бы понималась любым компьютером, имеющим представление об этом стандарте. В стандарте ASN.1 поэтому предъявляются жесткие правила кодирования даже на уровне отдельных битов информации, а также взаимного их расположения. Дополнительно нужно сказать, что стандарт ASN.1 кодирует информацию не в виде текста, а виде двоичных последовательностей. Сейчас уже появились вариации форматов кодирования, позволяющие представлять данные и в виде текста (XML), но обзор этих форматов выходит за рамки данной статьи. Здесь мы рассмотрим только самое сложное — двоичное кодирование (формат ASN.1 BER — Basic Encoding Rules).
Данные закодированные в формате ASN.1 представляют из себя последовательность байт (или "октетов"), которые идут один за другим, без каких либо разрывов. Последовательность закодированную в ASN.1 можно передавать по линиям связи, сохранять в файл — блок закодированной информации в ASN.1 уже содержит необходимое описание его общей длины и содержимого.
Для возможности подобного описания содержащейся в закодированном блоке информации применяется определенная общая структура каждого блока. Каждый блок содержит минимум 3 обязательных части (в отдельных случаях остаются только первые два блока, но эти случаи описываются отдельно):
Кроме этого может быть ещё 4-ая, не обязательная часть — часть октетов окончания значения блока (несколько октетов). Про эту часть будет рассказано несколько позже.
Перейдём к описанию каждой части ASN.1-кодированного блока.
Часть идентификатора блока состоит минимум из одного октета. Формат этого первого октета строго фиксирован.
В случае если идентификатор типа для блока находится в диапазоне значений 0-30 идентификационный блок состоит только из одного октета. Если же идентификатор типа для блока имеет значение 31 и выше, то в битах 5-1 выставляются все 1, а в последующих октетах кодируется нужный номер. Номер идентификатора типа кодируется как без знаковое целое, разложенное по основанию 128. В каждом октете, кодирующем идентификатор типа для блока, старший бит должен быть равен 1, кроме самого крайнего, завершающего октета (способ кодирования полностью совпадает со способом, которым кодируются SID для OBJECT IDENTIFIER, см. ниже).
Часть общей длины блока содержит минимум 1 октет, кодирующий длину значения, которое содержит блок (именно только длину блока, содержащего закодированное значение, а не общую длину всего закодированного блока вместе с идентификатором блока и частью общей длины!). Длина блока в простейшем случае кодируется как без знаковое целое, разложенное по основанию 128. Бит 8 (старший бит) в этом случае является дополнительным флагом. Если общая длина закодированного блока превышает 128, то старший бит первого октета части общей длины блока должен быть установлен в 1, а следующие 7 бит должны кодировать без знаковое целое значение количества последующих октетов, которые и будут кодировать реальную общую длину блока.
Например если общая длина блока равна L = 201 то она будет кодироваться с помощью двух октетов:
Кроме явного задания общей длины блока возможно определять окончание данного блока непосредственно в процессе декодирования блока. Это важно, когда при начальном кодировании блока не ясно, сколько именно октетов он будет содержать (потоковое кодирование). В этом случае первый октет части общей длины блока должен быть равен 80 (старший бит 8 равен 1 и все остальные биты равны 0). Окончание всего блока определяется по наличию в блоке значения двух последовательно идущих октетов 00 00.
Для начала немного теории, касающейся собственно чисел с плавающей запятой. Числа с плавающей запятой обычно представляют состоящими из трёх частей: мантиссы, основания и экспоненты. Более просто это можно объяснить с помощью формулы: REAL = (мантисса)*(основание)(экспонента). Если по этой формуле представлять обычные десятичные числа, то получится REAL = (мантисса)*10(экспонента). Так как в ASN.1 и мантисса и экспонента могут быть как положительными, так и отрицательными, то возможно как представление сколь угодно больших и сколь угодно маленьких значений, с произвольным знаком.
В отличие от обычного, машинного, представления чисел с плавающей запятой (IEEE 754) в ASN.1 тип REAL практически не ограничен по размеру как мантиссы (мантисса может состоять из практически не ограниченного числа октетов и представлять сколь угодно большое число), так и по размеру экспоненты (значение экспоненты также может состоять из произвольного количества октетов). Ограничения при кодировании накладываются только на значение "основания": в качестве "основания" могут выбраны только числа 10, 2, 8 или 16.
Для кодирования типа REAL применяются следующие три основных блока:
В служебной информационном октете содержится следующая информация:
Значение экспоненты числа кодируется целым числом, состоящим из произвольного количества октетов. Здесь необходимо сделать маленькое отступление и рассказать как именно в ASN.1 кодируются как положительные целые числа, так и отрицательные.
Положительные целые числа в ASN.1 представляют собой последовательность "индексов" при соответствующих степенях разложения по основанию 256. То есть целое число, представленное в обычном десятичном формате, сначала раскладывается по основанию 256, а потом индексы при соответствующих степенях 256 записываются в качестве кодирующих октетов. Для наглядного примера возьмём число 32639. Данное число разлагается по основанию 256 как: 3263910 = 127*2561 + 127*2560. Следовательно коэффициенты при соответствующих степенях 256 будут равны (127, 127). Представляя десятичное значение 127 в виде последовательности битов получаем: 127 = 0111 1111, или представляя каждую группу из четырех битов в качестве числа от 0 до F получаем: 127 = 0111 1111 = 7F. Таким образом начальное число 32639 будет кодироваться последовательностью из двух октетов 7F 7F.
Рассмотренным выше способом можно закодировать сколь угодно большое целое положительное число. Однако как быть с кодированием отрицательных целых значений? Именно для кодирования отрицательных целых применяется специальная процедура кодирования значений.
Для примера опять возьмем число 32639, но теперь пусть оно будет отрицательным (-32639). Кодирование отрицательных целых построено так, что на самом деле кодируется не одно, а два целых значения — одно основное значение и другое целое значение, которое нужно вычесть из основного значения. То есть при декодировании для получения закодированного отрицательного числа просто вычислить результат (x — y). Как видно из этой простейшей формулы если значение "x" меньше, чем значение "y" то результат будет меньше нуля (то есть отрицательное число).
Вышеупомянутые два числа (основное число и число, которое надо вычесть из основного) формируются по следующим правилам:
Перейдём к кодированию конкретного числа из примера (-32639). Так как число, которое надо вычесть из основного, должно быть больше основного числа, то кодирование отрицательных целых чисел начинается именно с выбора этого вычитаемого. Так как по правилам это вычитаемое должно разлагаться по основанию 256 так, чтобы все биты, представляющие индексы при соответствующих степенях 256, были равны 0 кроме первого бита, то ряд возможных вычитаемых представляет собой лидирующий октет 80 (1000 0000) и какое-то количество октетов 00, следующих за ним. То есть в качестве вычитаемых могут использоваться: 80 (12810), 80 00 (3276810), 80 00 00 (838860810) и т.п. Для кодирования нашего числа "-32639" выберем первое подходящее вычитаемое, большее кодируемого числа по модулю (то есть большее чем число 32639). Ближайшее такое число равно 32768 (80 00).
Теперь необходимо получить значение основного числа. Для этого надо опять решить простейшую формулу: x — 32768 = -32629. Решая уравнение получаем значение x = 129 = 129*2560, следовательно число 129 кодируется одним байтом 81256. Так как если более внимательно рассматривать правила то можно понять, что количество бит в основном и вычитаемом числах должно быть равно. Количество бит в вычитаемом равно 16. В то же время количество бит в основном числе равно всего 8. Для увеличения числа бит в основном числе просто добавим не значащие нули для старших бит. Тогда получим 129 = 0*2561 + 129*2560, а следовательно основное число будет кодироваться двумя октетами как (00 81). Теперь устанавливая первый бит в 1 для полученного двух октетного основного числа получаем окончательное число, которое кодирует "-32639". Это число будет кодироваться двумя октетами 80 81. Ещё раз — основное число образуется из всех битов закодированного числа, кроме самого старшего бита (получаем что основное число у нас кодируется 00 81), а вычитаемое число образуется только из одного первого бита, установленного в 1, и всех остальных бит, установленных в 0 (получаем, что вычитаемое число у нас кодируется как 80 00).
А теперь приятная информация — в современных компьютерных системах целые числа (как положительные, так и отрицательные) автоматически кодируются и хранятся именно в том формате, который и был описан выше. То есть для кодирования целых чисел в ASN.1 не нужно выполнять вообще никаких действий — просто нужно сохранить их байт за байтом и всё.
Значение мантиссы числа представляет собой всегда без знаковое целое. То есть мантисса числа, кодированного в ASN.1, всегда является положительным числом. Для того чтобы кодировать отрицательные числа с плавающей точкой в ASN.1 предусмотрен отдельный бит (бит 7) в служебном октете (см. выше).
Мантисса кодируется как последовательность байт представляющих собой коэффициенты разложения начального числа по основанию 256. То есть если мантисса числа в десятичном виде равна 32639 то значит закодированное число будет состоять из двух октетов 7F 7F (3263910 = 127*2561 + 127*2560 = 7F*FF1 + 7F*FF0).
Примеры кодирования чисел REAL в ASN.1 в двоичном представлении:
Следовательно все число с плавающей точкой из нашего примера (при условии "нормализации" мантиссы) будет кодироваться следующей последовательностью октетов:
Кроме кодирования всех частей числа с плавающей точкой в виде двоичного представления в разложении по различным степеням двойки дополнительно есть прекрасная возможность представлять подобные числа в ASN.1 в обычном строковом виде, в каком мы обычно и видим такие числа. В этом случае считается, что число кодируется с основанием 10.
При кодировании по основанию 10 дополнительно вводится понятие "форм представления числа". Всего таких форм 3 (формы NR1, NR2 и NR3) и описываются они в отдельном стандарте ISO 6093. Так как этот стандарт является платным, то для ознакомления с формами представления чисел можно порекомендовать "предка" ISO 6093 — стандарт ECMA-63, который легко может быть найден в Интернете.
При кодировании числа с плавающей точкой в представлении разложения по основанию 10 в служебном информационном октете указывается код формы представления числа (01, 02 или 03 для соответствующих форм), а сразу после служебного информационного октета указываются коды символов, представляющих кодированное число. Разрешены следующие коды символов:
Все остальные символы запрещены к кодированию (при декодировании символов, отличных от приведенных выше, декодер ASN.1 обязан выдать ошибку).
Примеры кодирования числа с плавающей точкой в десятичной форме:
Кроме обычных чисел ASN.1 позволяет кодировать также и ряд "специальных" чисел:
Все специальные числа кодируются только одним служебным информационным октетом, без указания октетов для экспоненты и мантиссы:
UPDATE: список последующих глав моей статьи
UPDATE #3: Возможно кто-то упустил, но вот тут находится реализация на С++ ASN.1 coder/decoder с поддержкой типа REAL. А вот тут реализация на JavaScript, но пока без типа REAL.
Укажите причину минуса, чтобы автор поработал над ошибками
Присылаем лучшие статьи раз в месяц
Скоро на этот адрес придет письмо. Подтвердите подписку, если всё в силе.
12 апреля 2021 10 недель 46 000 Loftschool
12 апреля 2021 10 месяцев 96 900 Нетология
Разработка под Android: базовый уровень
12 апреля 2021 6 недель 24 000 Loftschool
13 апреля 2021 18 месяцев 85 200 SkillFactory
14 апреля 2021 8 месяцев 87 900 Нетология
AdBlock похитил этот баннер, но баннеры не зубы — отрастут
Подробнее
Какое то время назад у нас в довольно большом международном банке нам предлагалось внедрить ASN как стандарт. Все обломалось на том, что компилятор был платный, и стоял только на одной тачке где-то в сиднее, а больше бизнес покупать не хотел. Все посчитали, что это усложнит дело :)
Надо посмотреть, какие сейчас есть компиляторы.
Валом решений и вполне по человеческим ценам.
Хотя бы www.obj-sys.com/asn1-compiler.shtml. На сайте цен нет, но свяжитесь, вполне нормально.
Есть еще, но материалы по сравнению разных решений на работе.
Есть открытые либы, но по отзывам разработчиков — править и править.
Во время подготовки моей статьи я использовал в частности «триальные» версии коммерческих компиляторов, в том числе и Objective Systems. Должен сказать, что из коммерческих компиляторов наиболее полно и правильно реализующим стандарт является только продукт OSS ().
Из свободно доступных порекомендовал бы ASN1C Льва Валкина ().
Почему-то ссылки не вставились… Пока осваиваюсь с Хабром, извиняюсь.
Да, кто-то должен бы написать про ASN.1. Спасибо.
С учетом того что почти все бинарные протоколы кодируются при помощи ASN (ну или CSN.1) люди начинали совсем по другому смотреть на проектирование протоколов. Даже был замечен отказ от XML )
В качестве хинта: в последние версии Wireshark встроен ASN диссектор. И на основании ASN нотаций можно собирать свои диссекторы.
Пишите еще )
>Одной из причин по которой сложилась ситуация, когда подавляющее большинство разработчиков программ считаю стандарт ASN.1 сложным
считают
>Длина блока в простейшем случае кодируется как без знаковое целое, разложенное по основанию 128
А из дальнейшего описания получается 256. Как правильно?
Так как первый бит используется для служебных целей то кодируется длина по основанию 128, но так как старший бит все-таки присутствует то «получается» 256.
Опубликована следующая часть моей статьи ASN.1 простыми словами (часть 2).
Опубликована третья, последняя, часть моей статьи ASN.1 простыми словами (часть 3, заключительная).
Юрий, скажите, а что послужило причинами такого сложного формата:
1. «Узкие» каналы связи 1984 году, требующие экономить каждый бит?
2. А давайте придумаем замороченный стандарт, чтоб люди покупали у нас «компилятор»!?
3. Что-то другое?
Эхх… 10 лет назад я сидел и вручную ковырял ASN.1 распечатывая листы А3 и обвешивая стены кабинета чтобы расшифровать данные в читабельный формат…
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.
mehcode opened this issue on 19 Sep 2019 · 0 comments
mehcode opened this issue on 19 Sep 2019 · 0 comments
This is explicitly for compatibility with the mobile wallets as they are today.
mehcode added this to Ready for Development in Board on 19 Sep 2019
mehcode moved this from Ready for Development to In Progress in Board on 19 Sep 2019
mehcode moved this from In Progress to Ready for Review in Board on 19 Sep 2019
Board automation moved this from Ready for Review to Done on 19 Sep 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Successfully merging a pull request may close this issue.
Макетирование на Veroboard stripboard и на простых stripboard...
ASN.1 простыми словами (кодирование типа REAL) / Хабр
Strip ASN.1 prefix from public keys on RequestToCreateAccount modal...
ESP LED Strip Board, Mosfet Drive - ElectroDragon
Practical Circuit Construction With Strip Board : 14... - Instructables
Sex 3d
Redhead Gloryhole
My Daughters Cunt
Asn Stripping Board



















































