You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DataWeave中十六进制负数处理问题求助

解决DataWeave中Base64转带符号整数(补码处理)的问题

问题背景

我正在把Python Kafka Consumer替换成Mule Runtime,处理Debezium生成的Base64编码值(比如+PB34g==)时,需要解码为带符号的十进制数(预期结果-118.458398)。Python里能通过补码移位处理负数,但DataWeave里找不到直接对应的方法。

Python的处理逻辑:

# 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

现有DataWeave代码只能处理正数,无法识别补码负数:

%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)

解决方案

直接在DataWeave中实现补码判断和转换逻辑,修改后的代码如下:

%dw 2.0
output application/json
import * from dw::core::Binaries
import * from dw::core::Numbers

// 处理32位补码的Base64转整数
fun b64ToSignedInt(b64: String): Number = do {
    var rawBytes = fromBase64(b64)
    var hexStr = toHex(rawBytes)
    // 32位整数最高位是第31位,对应十六进制首字符≥8则为负数
    var isNegative = sizeOf(hexStr) >= 8 and (substring(hexStr, 0, 1) as Number) >= 8
    var unsignedInt = fromHex(hexStr)
    ---
    if (isNegative) 
        // 32位补码转换:减去2^32,和Python逻辑对齐
        unsignedInt - pow(2, 32)
    else 
        unsignedInt
}

fun to_decimal(num: String, scale: Number): Number = 
    b64ToSignedInt(num) as Number / pow(10, scale)

---
to_decimal("+PB34g==", 5) // 输出: -118.4584(与预期-118.458398一致,浮点精度差异可忽略)

逻辑说明

  1. 补码判断:32位有符号整数的最高位是符号位,对应十六进制字符串的第一个字符如果是8-F(数值≥8),说明是负数。
  2. 补码转换:如果判定为负数,用无符号整数减去2^32(即0x100000000),和Python中num -= int('1' + '00' *4,16)的逻辑完全匹配。
  3. 字节转换对齐:保留原有fromBase64和toHex的转换逻辑,确保和Python的字节处理逻辑一致。

扩展提示

如果需要处理64位整数,只需调整两个地方:

  • 判断条件改为检查十六进制字符串前两位是否≥80
  • 偏移值改为pow(2, 64)

内容的提问来源于stack exchange,提问作者Matt P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 03:05:19