Engee documentation
Notebook

Working with strings using Engee blocks

In this example, we will create some "custom blocks" that will allow us to perform operations on strings as arrays.

Task Description

Sometimes working with strings requires the use of substantial mathematical apparatus, which in educational materials and articles is usually presented through flowcharts (for example, in cryptorgaphy). In such problems it is very useful to be able to quickly model the solution, explore alternatives and perform experiments. Representation of an algorithm in the form of blocks improves readability and simplifies work with their structure, allows to easily combine the algorithm with other stages of information processing, visualise interfaces, etc.

The custom blocks we have created for this example are intended to demonstrate one of the approaches for working with strings using graphical modelling tools in Engee.

post_pic_string_to_vector_blocks.png

In the properties of each block, there is a field through which you can enter a string.

image.png

Further work with this string is performed in the mask editor, which converts it into a numerical vector using the required method:

  • converts it to a bit representation,
  • or encodes each letter by its position in the Latin alphabet (in lower case - AbC becomes 123),
  • or does the same in the Cyrillic alphabet (бвГ becomes 234).

image.png

The mask performs preprocessing and converts the string entered in the "Text" field into the required encoding. It is also possible to organise encoding selection directly in the mask.

What the block mask does

A mask of each custom block:

  1. translates the text to the desired encoding and sets it as a parameter of Value block Constant, hidden under the mask,
  2. sets a special sampling time (SampleTime) to block Constant so that after passing through block Unbuffer the vector of output parameters is output one character per second,
  3. updates the appearance of the block.

Blocks return an array of some length. To make it easier to work with individual bits or symbols, the sampling step of the block output value is made equal to the length of the string. *If the integration step of the model is 1s, a string of 5 characters long will be output by the Constant block only every 5 seconds. After each such block there is an Unbuffer block, which decomposes the input vector into individual elements and returns an element for each simulation step.

Running the model

Start this model using software control commands:

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" );

Let's plot the output of the first block 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]:

We get the string "A" (Latin character A, code 0x41 or 65 in decimal system) in binary representation: 0100 0001.

To get the string in "byte representation" you can use the command codeunits(ваша_строка), but you should keep in mind that the source string is encoded in Unicode, so Cyrillic characters will be double-byte.

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

Conclusion

Representing a term as an array of numbers comes in handy in protocol analysis and cryptography.

The use of such blocks allows to hide unnecessary levels of technical work with strings from the profile specialist and concentrate on demonstration of the modelled process or algorithm.

Blocks used in example