消息可变长度指示器(VLI) 发送到BizSwitch或从BizSwitch发送的每条消息之前2个字节。这两个字节称为可变长度指示符。 字节1-2指示消息中的字节数(不包括前2个字节)。 2个字节代表16位无符号 网络字节顺序的整数。请注意,如果正在发送压缩消息,则该消息必须首先是 压缩后,才能确定其长度,然后再发送。 例如,假设您仅查看构成XML消息的文本(不包括2字节的标头) 一个特定的示例,然后您计算了字符,而它们恰好相加了299个字符。如果您采取了 科学计算器(例如Windows中的计算器),并且您在299中输入了“ Dec”(用于十进制),然后选择 “十六进制”,将显示的值是“ 12B”,表示与01 2B相同,这正是人们期望的值 查看消息的前两个字节是否已将消息转储到文件中,然后使用十六进制编辑器打开。 用于计算VLI的示例Java代码:
public byte[] wrap(byte[] msg) throws Exception {
int len = msg.length;
if (len > 65535) {
throw new IllegalArgumentException("Exceeds 65535 bytes.");
}
byte firstByte = (byte)(len >>> 8);
byte secondByte = (byte)len;
ByteArrayOutputStream baos = new ByteArrayOutputStream(len + 2);
baos.write(firstByte);
baos.write(secondByte);
baos.write(msg);
return baos.toByteArray();
}
public byte[] unWrap(InputStream inputStream) throws Exception {
int firstByte = inputStream.read();
if (firstByte == -1) {
throw new IOException("End of Stream while trying to read vli byte 1");
}
int firstByteValue = firstByte << 8;
int secondByteValue = inputStream.read();
if (secondByteValue == -1) {
throw new IOException("End of Stream reading vli byte 2." );
}
int len = firstByteValue + secondByteValue;
byte[] message = new byte[len];
int requestLen;
int readLen;
int currentIndex = 0;
while(true) {
requestLen = len - currentIndex;
readLen = inputStream.read(message, currentIndex, requestLen);
if (readLen == requestLen) {
break; // Message is complete.
}
// Either data was not yet available, or End of Stream.
currentIndex += readLen;
int nextByte = inputStream.read();
if (nextByte == -1) {
throw new IOException("End of Stream at " + currentIndex
);
}
message[currentIndex++] = (byte)nextByte;
}
return message;
}
这是我的python转换代码
import io
def wrap(msg):
msg_len = len(msg)
if msg_len > 65535:
return "Message exceeds 65535 bytes."
first_byte = bytes(msg_len >> 8)
second_byte = bytes(msg_len)
# create an empty bytearray
data_frame = bytearray()
data_frame.extend(first_byte)
data_frame.extend(second_byte)
data_frame.extend(msg)
return data_frame
def un_wrap(data_frame):
data_frame = io.BytesIO(data_frame)
first_byte = data_frame.read()
try:
first_byte == -1
except:
raise "End of Stream while trying to read vli byte 1"
first_byte_value = first_byte << 8
second_byte_value = data_frame.read(1)
try:
second_byte_value == -1
except:
raise "End of Stream reading vli byte 2."
byt_len = first_byte_value + second_byte_value
message = bytes(byt_len)
request_len = 0
read_len = 0
current_index = 0
while True:
request_len = byt_len - current_index
read_len = data_frame.read(message, current_index, request_len)
if read_len == request_len:
return "Message is complete."
# Either data was not yet available, or End of Stream.
current_index += read_len
next_byte = data_frame
if next_byte == -1:
return "End of Stream at " + current_index
message.extend(bytes(next_byte))
return message
这是越来越错误了
first_byte_value = first_byte << 8
TypeError: unsupported operand type(s) for <<: 'bytes' and 'int'
这是作为消息发送的内容,但是我需要两个字节来表示消息
<ipayMsg client="PESATRANS" term="00001" seqNum="0" time="2019-10-09 10:13:20 +0300">
<elecMsg ver="2.44">
<vendReq>
<ref>749761497475</ref>
<amt cur="KES">500</amt>
<numTokens>1</numTokens>
<meter>01450344831</meter>
<payType>cash</payType>
</vendReq>
</elecMsg>
</ipayMsg>
答案 0 :(得分:0)
在此行中,代码要对bytes对象进行左移。您需要先将其转换为int。
int_value = int.frombytes(bytes_value, byteorder="big")
文档:https://docs.python.org/3/library/stdtypes.html?highlight=from_bytes#int.from_bytes
答案 1 :(得分:0)
我已经找到答案了。我遇到的主要问题是假设python字节转换与java相同。 这是我的主要挑战所在。
public byte[] wrap(byte[] msg) throws Exception {
int len = msg.length;
if (len > 65535) {
throw new IllegalArgumentException("Exceeds 65535 bytes.");
}
byte firstByte = (byte)(len >>> 8);
byte secondByte = (byte)len;
ByteArrayOutputStream baos = new ByteArrayOutputStream(len + 2);
baos.write(firstByte);
baos.write(secondByte);
baos.write(msg);
return baos.toByteArray();
}
对于这种java方法,我能够针对python提出这一点
def wrap(msg):
msg_len = len(msg)
if msg_len > 65535:
return "Message exceeds 65535 bytes."
my_list = []
first_byte = msg_len >> 8
second_byte = msg_len
my_list.append(first_byte)
my_list.append(second_byte)
# create an empty bytearray
data_frame = bytearray([x % 256 for x in my_list])
data_frame.extend(msg)
return data_frame
首先,我创建了一个元素列表,然后从2s补码转换为无符号整数,然后将它们添加到字节数组中,从而实现了这一目标。
data_frame = bytearray([x % 256 for x in my_list])
原来,我不需要第二种方法。谢谢