# Thread: chr(0) should still be 1 character long

1. ## chr(0) should still be 1 character long

I've been having problems with Xor encryption and I've boiled it down to the fact that A5V6 sees chr(0) as a zero length character, when any other programming language will still see it as 1 character long.

e.g.

? len(chr(0) + chr(0))

this should result in 2, but it returns 0

Is there a way around this? I am in urgent need of fixing this as our credit card payments are being held up !

2. ## RE: chr(0) should still be 1 character long

Just to add to this, if I print this in visual basic for example:

debug.print "abc" + chr(0) + "def"
I get correctly "abc def" where the space is a null character.

If I do this in Alpha5 I get "abcdef"

If I write chr(0) to a file I get a 1 byte long file.

Seems like a bug to me

3. ## RE: chr(0) should still be 1 character long

The space character is actually chr(32). You can also use the space() function to generate an arbitrary number of spaces.

Chr(0) is a null, not a space. Strings are *terminated* by nulls. If what you say is correct, Visual Basic is the one handling this incorrectly. When determining the length of a *string*, in most languages, the length is determined by the position of the null character. This is different when dealing with binary streams of data, where the null has different significance.

? len(chr(32)+chr(32))
= 2

? "abc" + chr(32) + "def"
= "abc def"

4. ## RE: chr(0) should still be 1 character long

No, I want the null character - not a space - the .xor. returns 0 when true, I have to turn this into a chr to append to a string.

I will attach my code

cryptkey = "7wXyUNsD9MAix4wr"

function SimpleXor as C (InString as C, Key as C)

dim KeyList[len(key)] as N

for i = 1 to len(Key)
KeyList[i] = asc(substr(Key, i, 1))
next

for i = 1 to len(InString)
output = chr(asc(substr(InString, i, 1)) .xor. keylist[mod(i-1,len(Key))+1])
simplexor = simplexor + output
next

end function

The problem is when a character in the instring matches a character in the key the result of the .xor. is 0 and as you can see I need to build up a string - including these chr(0)'s

I've reproduced this in C, php and VB and they all handle it correctly.

5. ## RE: chr(0) should still be 1 character long

I can *guarantee* you that strlen() in C will not return the correct length if you have chr(0) in the middle of your 'string'. Strlen() uses the null as the termination character of a string, so strlen("abc\0def") will return 3.

The whole concept of doing an XOR as a a *string* doesn't make any sense at all. XORs produce binary data. If you want to do an XOR in Alpha Five, you need to use a Blob variable.

DIM b AS B
DIM cryptkey AS B

cryptkey = "7wXyUNsD9MAix4wr"
b = "fubar"
? b.dump()
= "66 75 62 61 72 00 "

b.xor(cryptkey)
? b.dump()
= "51 02 3a 18 27 4e "

...or you could just use our built in encrypt_string() function and pass it your key.

6. ## RE: chr(0) should still be 1 character long

I have little choice as how to send the information to our credit card people as they require the string as produced above then base64encoded.

cryptkey = "7QTyUNsR9MAux4wr"
cryptstring = "VendorTxCode=ZZ&amp;Currency=GBP"

dim sx as b
sx = SimpleXor(cryptstring ,cryptkey) 'my function in above post.

crypt = base64encode(sx) 'this is sent to protx

The problem arises when a character in the cryptstring matches a character in the key - the xor returns 0 - hence my chr(0) problem.

7. ## RE: chr(0) should still be 1 character long

I could give you examples in Perl, Jsp, Asp, VB, Php they all work as I described it should work - producing string variables containing chr(0). how else am I supposed to base64encode chr(0) ???

InString = "Antony"
Key = "ABCDEF"

instring xor'ed with key results in 0 44 55 43 43 63
the 0 is becuase A matches A

now, I need to base64encode this, and this can only be done using a string.... but Alpha5 wont let me insert chr(0) into the string...

8. ## RE: chr(0) should still be 1 character long

Anthony,

You really don't understand what I'm saying. The concept of an embedded null in a string is *nonsense*. A STRING ends when the null is reached...period. This is true in any language.

base64 encoding is designed to encode BINARY data...that's it's whole reason for existence...to turn BINARY data into STRING data for transmission (often by email) by taking 3 bytes of binary data and expand it into 4 bytes of readable string data. Yes, you can base64encode() strings, too, but if you have nulls in your data, it is, by definition, not a string.

If you want to base64encode a blob, use base64encode() and pass it the blob variable:

DIM b AS B
DIM cryptkey AS B

cryptkey = "7wXyUNsD9MAix4wr"
b = "fubar"
b.xor(cryptkey)
? base64encode(b)
= "UQI6GCdO"

If you need to embed nulls into the blob data, you can use b.poken(position, 0).

In your example Function SimpleXOR() above, I don't know how you modified it to accommodate for the binary data, so I can't really help you with your specific example. The function, at the least, needs to be defined AS B, rather than AS C, and internally, the value you build needs to be a blob variable, also. You can't just take a string and stuff it into a blob and expect it to handle the chr(0), since you are *starting* with a string, which can't have nulls.

9. ## RE: chr(0) should still be 1 character long

Let's step back for a second.

If you have a working php example, please post it and we can work from there.

10. ## RE: chr(0) should still be 1 character long

I played around with PHP some and determined that php does include nulls when printing and determining string lengths. Their internal string structure must maintain a separate length property. If you do the same thing in C, however

char szString[] = "foo\0bar";
printf("%s", szString)l

will display:
foo

The bottom line is, to emulate this behavior seen in php in Alpha Five, you need to work with blobs rather than strings.

11. ## RE: chr(0) should still be 1 character long

PHP uses binary strings rather than null terminated strings.

12. ## RE: chr(0) should still be 1 character long

Antony,
Can you try this out and see if you get the same results in Xbasic as you get in VB?

function SimpleXor as b (InString as C, Key as C)
dim bxor as b
bxor=char_to_blob(key)
dim KeyList[len(key)] as N

for i = 1 to len(Key)
KeyList[i] = asc(substr(Key, i, 1))
next

for i = 1 to len(InString)
output = asc(substr(InString, i, 1)) .xor. keylist[mod(i-1,len(Key))+1]
bxor.poke(i,output)
next
siz=bxor.size()
bxor.resize(siz-1)
simplexor=bxor
end function

dim out as b
out=SimpleXor("Antony","ABCDEF")

ui_msg_box("base64encode()",base64encode(out))

13. ## RE: chr(0) should still be 1 character long

Thanks for helping all, with a little tweaking I got it working perfectly :)

function SimpleXor as B (InString as C, Key as C)
dim bxor as B
bxor=char_to_blob(instring)
dim KeyList[len(key)] as N

for i = 1 to len(Key)
KeyList[i] = asc(substr(Key, i, 1))
next

for i = 1 to len(InString)
output = asc(substr(InString, i, 1)) .xor. keylist[mod(i-1,len(Key))+1]
bxor.poke(i,output)
next
simplexor=bxor
end function

14. ## RE: chr(0) should still be 1 character long

Thanks for helping all, with a little tweaking I got it working perfectly :)

function SimpleXor as B (InString as C, Key as C)
dim bxor as B
bxor=char_to_blob(instring)
dim KeyList[len(key)] as N

for i = 1 to len(Key)
KeyList[i] = asc(substr(Key, i, 1))
next

for i = 1 to len(InString)
output = asc(substr(InString, i, 1)) .xor. keylist[mod(i-1,len(Key))+1]
bxor.poke(i,output)
next
simplexor=bxor
end function

15. ## Re: chr(0) should still be 1 character long

Hi Aaron,

I am trying to do the same as Anthony and have used the same code. This does work perfectly on my machine, the problem is when it goes up to the credit card company they cant decode it properly when they are using their PHP code. It seems they get stuck with characters when turned to Blob.

Here is the original Encode PHP which you asked to see.
Code:
```function simpleXor(\$InString, \$Key) {
// Initialise key array
\$KeyList = array();
// Initialise out variable
\$output = "";

// Convert \$Key into array of ASCII values
for(\$i = 0; \$i < strlen(\$Key); \$i++){
\$KeyList[\$i] = ord(substr(\$Key, \$i, 1));
}

// Step through string a character at a time
for(\$i = 0; \$i < strlen(\$InString); \$i++) {
// Get ASCII code from string, get ASCII code from key (loop through with MOD), XOR the two, get the character from the result
// % is MOD (modulus), ^ is XOR
\$output.= chr(ord(substr(\$InString, \$i, 1)) ^ (\$KeyList[\$i % strlen(\$Key)]));
}

// Return the result
return \$output;
}```