Carry over incrementing bytes in an array - arrays

I'm testing to see how easily (or quickly rather) our encryption can be cracked. The encryption key is an array of byte (could be any variable length). So, starting from an array populated with all 0's, I need to increment one byte at a time starting with the first. When any byte reaches its max and goes back to 0, the next byte in the array needs to increment (carry over).
It would be simple if the array were a short fixed length - but I'm clueless how to do so in a variable array length.
Variable declared inside the thread:
FKey: array of Byte;
After each thread iteration, it calls this procedure to increment the key by one byte:
procedure TCrackThread.NextKey;
begin
//Increment first byte
//If max, reset to 0 and increment next byte
//Recursively check the same for each following byte in array
end;
How can I increment (starting from the first) the bytes and carry over to the next in this variable length array?

This snippet will increase the first element and will continue to do so with the array elements as long as they are 255. If so, they are reset to zero. The routine will stop as soon as the condition is not fulfilled or the index reached maximum.
var
k: Integer;
...
if (Length(fKey) > 0) then begin
k := 0;
Inc(fKey[k]);
while (fKey[k] = 255) do begin
fKey[k] := 0;
Inc(k);
if (k >= Length(fKey)) then
break;
Inc(fKey[k]);
end;
end;
This would convert an array 254,0,0 into 0,1,0
If you want a carry to ripple through before the first increment,
this code will do that:
procedure Next;
var
k: Integer;
carry: Boolean;
begin
if (Length(fKey) > 0) then begin
k := 0;
repeat
carry := (fKey[k] = 255);
if carry then begin
fKey[k] := 0;
Inc(k);
if (k >= Length(fKey)) then
break;
end
else
Inc(fKey[k]);
until not carry;
end;
end;
This will convert 255,255,0 into 0,0,1.

Related

How strings differ from massive(array) of chars in Pascal?

I have a problem. Why I can't assign the value of strings to strings, but with chars it works. Why ^^^^^^? Where's string? Why There's the a[i]?
Is it because internal representation of strings and chars?
program massive.pas;
type
chars = array [1..255] of char;
var
s,s1: string;
ch1,ch2: chars;
i: integer;
begin
s1 := '';
s := 'abrakadabra';
for i := 1 to 5 do
begin
s1[i] := s[i];
writeln(s1[i],#10,'^^^',s1,'^^^')
end;
ch2 := '';
ch1 := 'abrakadabra';
for i := 1 to 5 do
begin
ch2[i] := ch1[i]
writeln(ch2[i])
end;
writeln('%%%',ch2,'%%%');
for i := 1 to 5 do
writeln('&&&',s1[i],'&&&');
end.
*Output
a
^^^^^^
b
^^^^^^
r
^^^^^^
a
^^^^^^
k
^^^^^^
a
b
r
a
k
%%%abrak%%%
&&&a&&&
&&&b&&&
&&&r&&&
&&&a&&&
&&&k&&&
The main difference between type chars = Array[1..255] of Char and String is that a chars array has a fixed length, while the string has a dynamic length.
You did not say which compiler you use, but I do think that the String type is what in some Pascal editions is called a ShortString, with a max length of 255 chars. The space for 255 chars is preallocated and the structure includes a length field, that keeps track of assigned length of the string.
In your example, you assign s1 := ''; in other words the length is set to zero. Then you do a mistake in the for loop in assigning s1[i] := s[i]; without setting the length of s1.
Subsequent reading of s1 always return an empty string as the length field is 0.
If you would assign the characters to the string, e.g. as:
for i := 1 to 5 do
begin
SetLength(s1, Length(s1)+1);
s1[i] := s[i];
writeln(s1[i],#10,'^^^',s1,'^^^');
end;
then the result would be what you originally expected.
Still better to set the length to the final 5 before the for loop.
Of course there are other solutions too. One is to not set the length at all, but to concatenate the string in the loop and let it handle the length field by itself:
for i := 1 to 5 do
begin
s1 := s1 + s[i];
writeln(s1[i],#10,'^^^',s1,'^^^');
end;
Edit 24.12.2021:
In a comment you said: But I still don't understand, why, when i wrote s1[1] in the for loop, all worked?
...and presumably refer to this code just before end.:
for i := 1 to 5 do
writeln('&&&',s1[i],'&&&');
We need to look at the memory layout and know that the first byte of the memory allocated to s1 is the length of the string. It can be referred to as s[0]. Subsequent bytes hold the characters that make up the stored string and they can be referred to as s[1]..s[n].
The first byte was set to 0 when you wrote (in the very beginning):
s1 := '';
// memory content:
0
|_|_|_|_|_|_|_|_|_| ...
Then you added the characters to s1 by manipulating the memory directly when you wrote in the first for loop:
s1[i] := s[i];
// content after 5 characters
0 a b r a k
|_|_|_|_|_|_|_|_|_| ...
Because you did not use concatenation (or adjusted the length while you added the characters) the length is still 0.
Then at the end in the last loop, you fetch the characters again by accessing the memory directly, and get the result you do, seemingly correct, but badly misusing the string structure.

Assigning 1 bit values to a multidimensional array in Verilog?

I am writing a Verilog code in which a 1 bit input has to be serially assigned (bit-wise) to a 2D memory. As far as I understand if we make a memory then it can be assigned byte wise (or contiguously) only at run time. Is there any way I can easily fill up a multidimensional array bit wise in Verilog like in C. Here is a snippet of my code:
input in,clk;
reg [7:0] array [0:511];
reg [8:0] i=9'd 0;
reg [2:0] j=3'd 0;
always # (posedge clk)
begin
if (i<=9'd 511)
begin
if(j<=3'd 7)
begin
array[i][j]<=in;
j<=j+1;
end
else
j<=0;
i<=i+1;
end
else
i<=0;
end //end always
But this is not giving me the desired results in the post-route simulation. Any suggestions are welcome.
It is impossible for i & j to be above 511 & 7 respectively. Therefore, if (i<=9'd 511) and if(j<=3'd 7) will always evaluate to be true and the else condition is unreachable.
Furthermore your i<=i+1; does not have a condition statement so it will always incroment, updating the array in a diagonal: [0][0] -> [1][1] -> ... -> [7][7] -> [8][0] -> [9][1] -> .... I assume this is undesired.
To fill the byte before changing i, you should use something like this:
array[i][j] <= in;
if (j == 3'd7) begin
j <= 3'd0;
if (i == 9'd511) begin
i <= 0;
end
else begin
i <= i + 1;
end
end
else begin
j <= j + 1;
end
Since the addressable range is a power of two, you can simplify the logic
array[i][j] <= in;
j <= j + 1; // Reminder <= is eval now, update later
if (j == 3'd7) begin // 'j' here has the pre-eval value
i <= i + 1;
end
FYI: you should always run in simulation before post-route. It is way easier to debug RTL and a waveform.

VHDL: Is it possible to concurrently shift array elements?

I would like to crearte own implementation of insertion sort for learning purposes.
As you may now, one of the steps reqiure shifting array elements to right by 1. The main difficulty here that the range of this operation has to be dynamic.
so if sort_reg is array from 0 to array_length, I need to acheive sort_reg(n)<=sort_reg(n-1), sort_reg(n-1)<=sort_reg(n-2) ... sort_reg(n-i+1)<=sort_reg(n-i); (n-m)>=i>=1, where m starting array index of the range, which would be shifted right by 1 from range ( m to n-1) to (m+1 to n).
The question is if it is possible to acheive this in one step, and then how?
Yes, it is possible in one step. You must store the element in registers and than assign the new value for all array elements at the same rising edge.
Let's make a simple example with just two signals a and b of type std_logic. Then this process would swap both elements at the rising edge of the clock:
process(clock)
begin
if rising_edge(clock) then
a <= b;
b <= a;
end if;
end process;
This works, because the signals get there new values after the process has finished. Thus, in the assignment of b the old value of a (before the rising clock edge) is assigned.
Let's continue with your example.
You didn't specify an specific array, so I take this one:
type array_type is array(0 to SIZE-1) of std_logic_vector(7 downto 0);
signal sort_reg : array_type;
Then the process can be written using a for loop.
EDIT: Within each iteration step, anif statement can be used to check if an element should be actually shifted. The signals n and m should be of type unsigned (prefered), or integer with range 0 to SIZE-1.
EDIT 2: Example changed to rotation as indicated in comments.
-- value to insert in case of rotation
value_to_insert <= sort_reg(to_integer(n)); -- to_integer required if type of 'n' is unsigned
process(clock)
begin
if rising_edge(clock) then
-- This loop is unrolled by the synthesis tool.
for i in SIZE-1 downto 1 loop
-- shift elements [n-1:m] to [n:m+1]
if (i <= n) and (i >= m+1) then
sort_reg(i) <= sort_reg(i-1);
end if;
-- insert new value
if i = m then
sort_reg(i) <= value_to_insert;
end if;
end loop;
-- insert into position zero
if m = 0 then
sort_reg(0) <= value_to_insert;
end if;
end if;
end process;
How about this;
sort_reg <= sort_reg(1 to sort_reg'high) & sort_reg(0);
I'm assuming sort_reg is a signal defined as;
signal sort_reg : some_array_type(0 to N);
In this case sort_reg'high is an attribute that is equal to N.
In vhdl & is used as concatenation operators. It joins two vector/arrays together to form a single vector/array.
Above example shifts only by 1 item. If you want to shift by M, you can use something like this;
sort_reg <= sort_reg(M to sort_reg'high) & sort_reg(0 to M-1);
Note that if you want to shift a signal (not assign it to a different signal) you should do it in a process as described by Martin.

Comparing input signal with array values

As I wrote in my previous post Synthesizable array of XY values
I wanted to create an array in Verilog to store x, y values of a given function.
Now I want to compare an input with x values of this array. If the value is within a specific region I want to save the index of this region and perform an addition with y with the same index. The result goes to the output. The code compiles just fine but its not synthesizes any circuit. The idea later is to use this array to perform linear interpolation and determinate the value of y for a given value of x that its not inside the array. The code is the following. I save the save value for x and y for each index.
module memc (inp,outp,clk,reset);
input[2:0] inp;
input clk, reset;
output[2:0] outp;
reg[2:0] outp;
wire [2:0] test;
reg [5:0] mem[2:0];
always #(posedge clk)
if (reset == 1'b1) begin
mem[0] <= {3'b000, 3'b000};//y0,x0
mem[1] <= {3'b001, 3'b001};//y1,x1
mem[2] <= {3'b010, 3'b010};//y2,x2
end
assign test ={inp<mem[0][2:0],inp<mem[1][2:0],inp<mem[2][2:0]}; //create a test vector by comparing inp with xo,x1,x2
always #(test)
case (test)
3'b1xx: outp=mem[0][2:0]+mem[0][5:3];//if 0<inp<x1
3'b0xx: outp=mem[1][2:0]+mem[1][5:3];//if x1<inp<x2
3'b00x: outp=mem[2][2:0]+mem[2][5:3];//if x2<inp<x3
default: outp=3'b00;
endcase
endmodule
Firstly, all three of your if conditions are the same (inp > mem[0][2:0]). I'm assuming you want
always #(*)
begin
if (inp > mem[0][2:0] ) //index 0
begin
index = 0;
end
else if (inp > mem[1][2:0] ) // index 1
begin
index = 1;
end
else if(inp > mem[2][2:0] ) // index 2
begin
index = 2;
end
end
Secondly, if you are using a large array (hard to be exact on the size), the latency from inp -> outp will get quite long, and you may get timing violations, depending on your clock speed. In that case, you'd be better off building a very simple FSM, and checking one or two entries per clock cycle instead. Just something to keep in mind moving forward.

Inno Setup Acces violation increment array of strings

I hava an array of strings. I increment this array when it is necessary with the function:
function insertMessageAction(list: TMessagesActions; message: String): TMessagesActions;
var
lenght: integer;
begin
if message <> '' then begin
lenght := GetArrayLength(list);
SetArrayLength(list, lenght +1);
if GetArrayLength(list) > lenght then begin
list[lenght] := message
end;
end;
result := list;
end;
If de increment is of 0 to 2, no problems, by when I increment to 3 lenght, the array is corrupted and 'value' of list is: "Acces violation at address 00403498. Read of address 0000006A".
It is impossible to create more long arrays of 2 items (strings)? There is limit of characters?
Thanks.
First of all, do not use array for your task. Memory reallocation that happens when changing the size of your string array is an expensive operation. What's more, you were trying to return a copy of that input array (in a wrong way), which would be unecessarily inefficient too.
I strongly suggest you to use the TStringList which is intended to be used for a collection of strings. By using TStringList, the whole code from your question would become:
StringList.Add(Message);
But to your question. It is possible, but you need to comply with a few things; at least:
Do not attempt to return an input array passed by reference:
Result := list;
If you need to have an array as a return type for some reason, allocate the size of this output array and copy all the elements from the input array:
InputLen := GetArrayLength(List);
SetArrayLength(Result, InputLen + 1);
for I := 0 to InputLen - 1 do
Result[I] := List[I];
Result[InputLen] := Message;
If you'd still like to stay by array, better pass it by variable parameter:
[Code]
type
TMessagesActions = TArrayOfString;
procedure InsertMessageAction(var AList: TMessagesActions;
const AMessage: String);
var
ArrayLen: Integer;
begin
ArrayLen := GetArrayLength(AList);
SetArrayLength(AList, ArrayLen + 1);
AList[ArrayLen] := AMessage;
end;

Resources