tags:

views:

610

answers:

5

Hi, I'm trying to increment an hex string like this:

#$67#$1c#$87#$b1;
#$67#$1c#$87#$b2;
#$67#$1c#$87#$b3;

Here's my procedure:

var test : array [0..3] of char; intSequence : cardinal;

Sequence := #$67#$1c#$87#$b1;

procedure IncSequence;
begin
  move(Sequence[1],intSequence,SizeOF(Sequence));
  inc(intSequence);
  move(intSequence,Sequence[1],SizeOf(test));
end;

Whith this procedure, only the second byte increment. The result is:

#$67#$1D#$87#$B1  
#$67#$1E#$87#$B1 
#$67#$1F#$87#$B1 

Thanks

+1  A: 

If you want to increment the sequence, you should do something like:

move(Sequence[0], intSequence, SizeOf(Cardinal));
inc(intSequence);
move(intSequence, Sequence[0], SizeOf(Cardinal));

Your code doesn't work because Sequence[1] points to the second byte of Sequence (arrays start with 0) and both Sequence and test consist of bytes/chars, so only 1 byte gets transferred.

EDIT: After trying this, I saw that intSequence is stored in "backwards" byte order, this increments the first byte of Sequence, so you perhaps want to reverse Sequence before.

schnaader
+1  A: 

You have three problems here:

  1. SizeOf(Sequence) is not the length of a sequence.
  2. You defined your sequence type as [0..3], so you need to start the index as 0
  3. endian issues. On little endian machines, even if you'll do the indexes and lengths right, you'll get #$67#$1c#$87#$b1 #$68#$1c#$87#$b1 #$69#$1c#$87#$b1 ... For solution to this problem, see this article
jpalecek
Initialy, i was using a string and didn't change my array offset for the array of char. Just a mistake. My main problem was the endian-ness. I've followed your article and everything work great now. Thanks!
+7  A: 

You could also do this by creating a "variant record" and just using Inc();

type
  testrec = record
    case Byte of
      0: (data: array[0..3] of AnsiChar);
      1: (intSequence: Integer);
  end;
var
  Sequence: testrec;
begin
  Sequence.data = #$b1#$87#$1c#$67; // reversed because of "endian-ness"
  Inc(Sequence.intSequence);
end;

In this case, the data and intSequence fields "overlay" each other in memory, so any writes to one field will immediately reflect in the other.

Allen Bauer
IMO this is THE Pascal way!To nitpick, the record syntax should have parens: 0: (data: array[0..3] of AnsiChar); 1: (intSequence: Integer);And because of the endian game, the sequence should be reversed: Sequence.data := #$b1#$87#$1c#$67; showmessage(Format('%x',[sequence.intsequence]));
François
Good points. I edited the answer.
Allen Bauer
You could do this: Sequence.data := #$67#$1D#$87#$B1 {not reversed}; Sequence.intSequence := ntohl(Sequence.intSequence); ntohl can be found in the Winsock unit. An added benefit is that the code would work on non-little endian processors with just a rebuild.
dangph
That's the best version! I knew that in C, there are unions, but I often forget that there are similar ways to do this in Delphi!
schnaader
Your solution work great especially with the ntohl function! Thanks for your responses.
+1  A: 

Warning, not a Delphi expert

Don't do string manipulation and don't use an array of integers.

What you want is to increment a number, so do that! A hex number represents a single integer, not an array of integers.

  1. Convert Hex String to Integer
  2. Increment Integer
  3. Convert Integer to Hex String

Don't complain to me that this is inefficient, it is correct, simple and obvious. That's how code should be.

And if your hex string is too large to fit in an integer, then go ahead and use an array of integers, just make sure to encapsulate that so it looks like your dealing with one type. You can then test this array of integer type separately

Pyrolistical
+1  A: 

I think I see what's really going on here:

I believe this is Delphi 2009. Char is actually a UnicodeChar which is a TWO byte variable.

Increment the 4th byte and what are you really changing? The low order byte of the second character--producing exactly the output shown. Had you caused it to wrap past $FF you would have seen a very different result!

Sorry I can't provide more info, I haven't upgraded yet.

Loren Pechtel