处理负数十六进制在DataWeave



我正在努力让一个Python Kafka消费者退出使用Mule运行时。

我遇到了DataWeave和位操作符的阻塞,特别是如何处理负十六进制数。

目前,我的Kafka/Debezium生产者提供以下值+PB34g==,应该解码为-118.458398

在Python中,我可以使用Two's Complement来移位并转换为负数。但是,我还没有找到一个类似的DataWeave解决方案。

用这个函数解码Base64值,然后用下面的函数将其转换为整数。

# decode the integer
# and handle negative values
def _b64_to_int(self, value):
num = int.from_bytes(base64.b64decode(value), 'big')
# now check the sign
# and if negative, take 2's complement
# TODO: works, but isn't 64-bit safe
if num & (1 << 31):
num -= int('1' + '00' * 4, 16)
#print(f"{value} = {num}")
return num

我可以在Java类中处理这个问题,但如果可能的话,我更愿意使用DataWeave。

# and handle negative values
def _b64_to_int(self, value):
num = int.from_bytes(base64.b64decode(value), 'big')
# now check the sign
# and if negative, take 2's complement
# TODO: works, but isn't 64-bit safe
if num & (1 << 31):
num -= int('1' + '00' * 4, 16)
#print(f"{value} = {num}")
return num

我有以下DataWeave从Base64转换到一个数字。我发现这篇文章中创建了自定义的按位函数,但它们不处理负值。

%dw 2.0
output application/json
import * from dw::core::Binaries
fun to_number(b64) = dw::core::Numbers::fromHex(toHex(fromBase64(b64)))
fun to_decimal(num, scale) = to_number(num) as Number / pow(10, scale)
---
to_decimal("+PB34g==", 5)

我将Python代码段中的逻辑翻译为DataWeave,并从DataWeave脚本中添加了to_decimal()函数,以获得预期的结果。

我还没有验证它的逻辑和数学。

%dw 2.0
output application/json
import * from dw::core::Binaries
import * from dw::core::Numbers
var leftshift_1_31=fromBinary("10000000000000000000000000000000")
var hex_100000000="0100000000"
fun AND(bin1, bin2) = do {
var b1=getBinary(bin1, 64)
var b2=getBinary(bin2, 64)
---
fromBinary(b1 map ($ as Number * b2[$$] as Number) reduce ($$++$))
}
fun getBinary(i: Number, size: Number) = do {
var b = toBinary(i)
---
dw::core::Strings::leftPad(b, size, '0') splitBy ''
}
fun to_number(b64) = do {
var result = dw::core::Numbers::fromHex(toHex(fromBase64(b64)))
---
if ((AND(result, leftshift_1_31)==0))
result 
else
result - dw::core::Numbers::fromHex(hex_100000000) 
}
fun to_decimal(num, scale) = to_number(num) as Number / pow(10, scale)
---
to_decimal("+PB34g==", 6)

输出:

-118.458398

相关内容

  • 没有找到相关文章

最新更新