Need help figuring out bitwise operations

I need to calculate checksums to send SysEx to an external device. The calculation is simple - I need to XOR all bytes and then AND 7F.

The device ID is F0 00 01 74 11, let’s say I send a command ID 11 and value 01, so the bytes I need to calculate the checksum for are F0 00 01 74 11 11 01.

Using any tool for bitwise calculations I get 84 AND 7F = 04. Which is correct and the sysex command works as intended (it’s F0 00 01 74 11 11 01 04 F7).

But when I try to do it in GPScript, XORing the bytes gives me 57, and ANDing also 57.

What am I missing here?

How about you show us your GPScript?

As does GPScript

Var 
    dxor: Integer = F0 Xor 00 Xor 01 Xor 74 Xor 11 Xor 11 Xor 01;
    dxorf: Integer = dxor And 0x7F;

Initialization
    Print ("xor result " + IntTo7BitHexString(dxor,1));
    Print ("and result " + IntTo7BitHexString(dxorf,1));
End

This is what I get

You are applying xor to decimal numbers, not hex numbers.

What’s the right way to convert a string to hex numbers? I assume there is a way to do it without parsing the string into an array etc.?

How would you store a long sequence of numbers (that don’t fit in an integer variable) other than in an array?

Use either of these

    x : SysexMessage = # F0 12 34 F7
    y : SysexMessage = "F0 12 34 F7"

and then use the SM_GetValue to retrieve the individual values

Also understand that when you wrote F0 in your first example, you were not writing a Hex number. You were specifying a MIDI value for F in octave 0

That’s the piece of info I needed, thanks a lot!

I don’t make the rules, that’s how checksum is calculated for this equipment. :man_shrugging:

While we’re at it, I have another question. I need to convert decimal values to two byte hex, and the integer to 7 bit hex string function creates values like 0057, while I need it to be 57 00 (guess that’s the least/most senior byte thingie). Is there a simple way to do it or do I need to use an array here as well?

Hmm, we clearly need a couple of new functions to make this easier.
In the meantime, try something like this

function ReverseStringBytes(input : String) returns String
var
   len :integer = Length(input)
   
   index : integer
   size : integer = len /2
   
   if len % 2 == 0
      then
         result = ""
         for index = size - 1; index >= 0 ; index = index - 1
            do
              result = result + CopySubstring(input, index * 2, 2)
          end
      else result = "Invalid hex string"
   end   
End

That’s like 20% of code I would have written to do this. :slight_smile:

Thank you, as always!