Denys Vitali
Denys Vitali

Reputation: 530

Encoding.ASCII.GetBytes(cArr) in Crystal

I'm converting some C# code into Crystal code for a project: my goal is to convert a string into an ASCII Byte array.

C# code

The C# code is the following:

string expression = "nYrXa@9Q\x00bf1&hCWM\\9(731Bp?t42=!k3.";
char[] cArr = expression.ToCharArray();
byte[] bytes = Encoding.ASCII.GetBytes(cArr);

Which gives:

{byte[32]} = 110, 89, 114, 88, 97, 64, 57, 81, 63, 49, 38, 104, 67, 87, 77, 92, 57, 40, 55, 51, 49, 66, 112, 63, 116, 52, 50, 61, 33, 107, 51, 46

Crystal implementation

temp = "nYrXa@9Q\x00bf1&hCWM\\9(731Bp?t42=!k3."
byteDecKey = temp.to_slice
array = [] of UInt8
temp.each_char do |char|
    array << char.bytes[0] unless !char.ascii?
end

puts "EachChrKey: #{array}"
puts "ByteDecKey: #{byteDecKey}"

Result:

EachChrKey:      [110, 89, 114, 88, 97, 64, 57, 81, 120, 48, 48, 98, 102, 49, 38, 104, 67, 87, 77, 92, 57, 40, 55, 51, 49, 66, 112, 63, 116, 52, 50, 61, 33, 107, 51, 46]
ByteDecKey: Bytes[110, 89, 114, 88, 97, 64, 57, 81, 120, 48, 48, 98, 102, 49, 38, 104, 67, 87, 77, 92, 57, 40, 55, 51, 49, 66, 112, 63, 116, 52, 50, 61, 33, 107, 51, 46]
C Sharp   : Bytes[110, 89, 114, 88, 97, 64, 57, 81, 63, 49, 38, 104, 67, 87, 77, 92, 57, 40, 55, 51, 49, 66, 112, 63, 116, 52, 50, 61, 33, 107, 51, 46]

Am I doing something wrong?

Upvotes: 2

Views: 390

Answers (1)

Stephie
Stephie

Reputation: 3175

In your C# code, \x00bf is being interpreted as an escape code representing the byte 0xbf, whereas in crystal, strings do not support \x escape codes as strings can contain only valid unicode. Therefore the contents of the string contain the characters x00bf instead of the signal byte 0xbf. Encoding.ASCII.GetBytes seems to replace the unknown byte 0xbf with ?.

I'd suggest using Slice(UInt8) for holding binary data, and using some encoding method such as base64 to transport the data if it's required as a string. Strings are meant to contain only valid unicode, not arbitrary data.

Upvotes: 3

Related Questions