Документация Engee
Notebook

Работа со строками при помощи блоков Engee

В этом примере мы создадим несколько "пользовательских блоков", которые позволят нам выполнять операции над строками в виде массивов.

Описание задачи

Иногда работа со строками требуется применения существенного математического аппарата, который в учебных материалах и статьях принято представлять через блок-схемы (например, в крипторгафии). В таких задачах весьма полезно иметь возможность быстро моделировать решение, исследовать альтернативы и производить эксперименты. Представление алгоритма в виде блоков улучшает читаемость и упрощает работу с их структурой, позволяет легко объединять алгоритм с другими этапами обработки информации, визуализировать интерфейсы и т.д.

Пользовательские блоки, созданные нами для этого примера, призваны продемонстрировать один из подходов для работы со строками средствами графического моделирования в Engee.

post_pic_string_to_vector_blocks.png

В свойствах каждого блока есть поле, через которое можно ввести строку.

image.png

Дальнейшая работа с этой строкой осуществляется в редакторе масок, который преобразует ее в численный вектор по требуемому методу:

  • переводит в битовое представление,
  • либо кодирует каждую букву через ее положение в латинском алфавите (в нижнем регистре - AbC станет 123),
  • либо делает то же самое в кириллическом алфавите (бвГ станет 234).

image.png

Маска осуществляет предобработку и преобразует строку, введенную в поле "Текст", в нужную кодировку. Возможно также организовать выбор кодировки прямо в маске.

Что делает маска блока

Маска каждого пользовательского блока:

  1. переводит текст в нужную кодировку и проставляет ее в качестве параметра Value блока Constant, скрытого под маской,
  2. проставляет блоку Constant особое время дискретизации (SampleTime), чтобы после прохождения через блок Unbuffer вектор выходных параметров выдавался по одному символу в секунду,
  3. обновляет внешний вид блока.

Блоки возвращают массив некоторой длины. Чтобы облегчить работу с отдельными битами или символами, шаг дискретизации выходного значения блока делается равным длине строки. При шаге интегрирования модели 1с, строка длиной 5 символов будет выдаваться блоком Constant лишь каждые 5 секунд. После каждого такого блока находится блок Unbuffer, который раскладывает входной вектор на отдельные элементы и возвращает по элементу за каждый шаг симуляции.

Запуск модели

Запуск этой модели при помощи команд программного управления:

In [ ]:
# Загрузим модель, если она еще не открыта на холсте
if "string_to_bytes_model"  getfield.(engee.get_all_models(), :name)
    engee.load( "$(@__DIR__)/string_to_bytes_model.engee");
end

model_data = engee.run( "string_to_bytes_model" );

Построим график вывода первого блока Unicode String To Bytes:

In [ ]:
data_frames = collect( model_data["Unicode String To Bytes.1"] );
data_stream = collect( model_data["Unbuffer.1"] );

plot(
    plot( data_frames.time, hcat( data_frames.value... )' .+ (0.01.*collect(1:8))', st=:step, markershape=:circle, title="Кадры (8 бит в каждом + смещение для визуализации)" ),
    plot( data_stream.time, data_stream.value, st=:step, markershape=:circle, title="Поток битов" ),
    layout=(2,1), legend=false
)
Out[0]:

Мы получаем строку "A" (латинский символ A, код 0x41 или 65 в десятеричной системе) в бинарной репрезентации: 0100 0001.

Получить строку в "побайтовом представлении" можно при помощи команды codeunits(ваша_строка), но стоит иметь в виду, что исходная строка закодирована в Unicode, из-за чего кириллические символы будут двухбайтовыми.

In [ ]:
codeunits( "Привет" )'
Out[0]:
1×12 adjoint(::Base.CodeUnits{UInt8, String}) with eltype UInt8:
 0xd0  0x9f  0xd1  0x80  0xd0  0xb8  0xd0  0xb2  0xd0  0xb5  0xd1  0x82

Заключение

Представление срок в виде массива чисел пригодится в задачах анализа протоколов и криптографии.

Использование подобных блоков позволяет скрыть от профильного специалиста ненужные уровни технической работы со строками и сосредоточиться на демонстрации моделируемого процесса или алгоритма.

Блоки, использованные в примере