unicode in to_b
uptownhr opened this issue · comments
Just got to my first test message class. After sending in some initial values, and using the to_b method to see the result, i'm seeing a bunch of "\u" texts in the beginning. Do you know why this is happening or help explain what is going on and what I can do to remove this?
class Message < ISO8583::Message
mti_format ISO8583::N, :length => 4
mti 0100, "Authorisation Request"
bmp 2, "Primary Account Number (PAN)", ISO8583::LLVAR_N, :max => 19
bmp 3, "Processing Code", ISO8583::N, :length => 4
bmp_alias 2, :pan
end
message = Iso::Omnipay::Message.new 0100
message[2] = '4242424242424242'
message[3] = '0001'
message.to_b #0064`\u0000\u0000\u0000\u0000\u0000\u0000\u00001642424242424242420001
i'm seeing a bunch of "\u" texts in the beginning
unfortunately ruby is not very good at handling byte data. This is how ruby escapes strings to represent the binary 0x00 values in the initial bitmap.
message._body
["`\x00\x00\x00\x00\x00\x00\x00", "1642424242424242420001"]
Sorry, I'm having hard time following, is _body[0], the hex bitmap for the message? Where would be the best place to modify this? I'm assuming defining bm1?
I'm having a hard time following as well :) How does this relate to the last question? What are you trying to do? In general, you shouldn't need to touch any _underscore methods, consider them private.
:). I'm trying to get the bitmap representing the message. the \x00 doesn't seem to be right according to the the bms 2 an 3. I'm trying to get the hex of 011 representing the bits that are being sent
What do you mean by "the hex of '011' "?
Can't really say what's wrong off the bat, without actual working code (also, what ruby version?).
One things I noticed: 0 prefixing is octal (just as 0x prefixing is hex), so 0100 is probably not what you intend...
sorry, i'm trying to get my head wrapped around this right now. Basically here's the code that I'm working on and what I'm expecting to achieve.
For omnipay, BM1 contains the message_type, primary_bitmap, and secondary_bitmap
The primary_bitmap is a 16 byte hex that represents 64BMs that are going to be a part of the message. *first byte is a conditional indicator for the prescense of the secondary_bitmap
For example,
BM1
:message_type => N, :length => 4
:primary_bitmap => N, :length => 16
:secondary_bitmap => N, :length => 16 #conditional if first it in primary_bitmap is on
primary_bitmap = 011 .......... 64 Represents that bits 2 and 3 are being sent. #in hex, 6000000000000000
pan = 4242424242424242
processing_code = 0001
The full byte message with the message length would look as follows,
00400100600000000000000042424242424242420001
Basically, my primary goal is to manually get the primary_bitmap. As to the current .to_b is not resulting in the correct length.
Basically here's the code that I'm working on and what I'm expecting to achieve.
I think you forgot to provide a link to the code?
For omnipay, BM1 contains the message_type, primary_bitmap, and secondary_bitmap
Generally, the mti (message type) is not part of bmp 1. Can you provide the docs of the format you're implementing?
Basically, my primary goal is to manually get the primary_bitmap. As to the current .to_b is not
resulting in the correct length.
You're calling to_b on the entire message, so you're getting back the entire message. Have a look at the bitmap test cases, if you're only interested in generating/decoding bitmaps.
Here's the method I wrote to mimic what I want.
def get_message
message_data = _body[1]
#get used bits
used_bits = @values.map do |v|
v[0]
end
primary_bitmap = ''
#create 1st bit on bitmap depending on if BMS > 64 are set
if used_bits.any?{ |bit| bit > 64 }
primary_bitmap << '1'
secondary_map = true
else
primary_bitmap << '0'
secondary_map = false
end
#get primarybitmap
(2..64).each do |i|
if used_bits.any? { |bit| bit == i }
primary_bitmap << '1'
else
primary_bitmap << '0'
end
end
#convert to hex
primary_bitmap_hex = primary_bitmap.to_i(2).to_s(16)
#run secondary bitmap if 1st bit is set
secondary_bitmap = ''
secondary_bitmap_hex = ''
if secondary_map
(65..128).each do |i|
if used_bits.any? { |bit| bit == i }
secondary_bitmap << '1'
else
secondary_bitmap << '0'
end
end
secondary_bitmap_hex = secondary_bitmap.to_i(2).to_s(16)
end
bm_message = self.mti + primary_bitmap_hex + secondary_bitmap_hex + message_data
res = bm_message.length.to_s.rjust(4,'0') + bm_message
return res
end
Ok, still not sure what you are trying to do. If you just want to create a bitmap with the proper bits set, use the bitmap class directly instead of generating an entire message and then stripping the message off the bitmap. Like so:
require 'iso8583/bitmap'
bitmap = ISO8583::Bitmap.new
[4,6,8].each {|b| bitmap.set(b)} # or bitmap[b] = true
[4,5,6,7,8].each {|b| puts "#{b} ? #{bitmap[b]}"}
puts bitmap.to_s
This outputs:
4 ? true
5 ? false
6 ? true
7 ? false
8 ? true
0001010100000000000000000000000000000000000000000000000000000000
You can access the raw bytes using Bitmap's to_bytes
method