【问题标题】:Base64 Decode Pure JavascriptBase64 解码纯 Javascript
【发布时间】:2021-09-25 16:55:56
【问题描述】:

我正在尝试使用 Snowflake 中的用户定义函数对来自 Kafka Debezium Payload 的值(16 位签名大端序)进行 base64 解码。不幸的是,我只能使用 Javascript,而 Snowflake 使用 Javascript 标准库。我找到了一个 NodeJS 的工作示例,它使用了 Buffer 模块,但在 Javascript 中不可用。

 var kafkaDecodeNumber = function(base64EncodedNumber) {
     var byteArray = Buffer.from(base64EncodedNumber, 'base64');
     var value = 0;
     for (var i = 0; i < byteArray.length; i++) {
         value = (value * 256) + byteArray[i];
     }
     return value;
 };

var float = parseFloat(kafkaDecodeNumber( price )).toFixed(38) / 100

这是我在其他地方使用的一些工作代码示例

Python

    ctx = decimal.Context()
    ctx.prec = 38
    result = ctx.create_decimal(
        int.from_bytes(base64.b64decode(byte_value), byteorder='big')
        ) / 100
    return result

红宝石

event.get('price').unpack1('m*').unpack1('B*').to_i(2) / 100.0)

这里的任何帮助都会很棒!

【问题讨论】:

  • 你能提供一个编码字符串的例子和预期的解码结果吗?
  • 当然!解码强:“D6A =”预期结果为数字:40
  • new DataView(new Uint8Array(atob(base64EncodedNumber).split('').map(v =&gt; v.charCodeAt(0))).buffer).getInt16(0);
  • @Bravo 的输出是正确的,但是,在 Snowflake 中执行时出现以下错误:
  • 一旦我将new Uint8Array 更改为new Uint16Array,它似乎就可以工作了。谢谢!

标签: javascript apache-kafka base64 debezium


【解决方案1】:

以下是使用 atob(根据需要填充)Uint8Array 和 DataView 的方法

注意,原始 data 数组被“填充”为偶数长度 - 但我相信最后两个字节需要交换

var kafkaDecodeNumber = function(base64EncodedNumber) {
    var data = atob(base64EncodedNumber).split('').map(v => v.charCodeAt(0));
    if (data.length % 2) {
        data.push(0, data.pop());
    }
    var uint8 = new Uint8Array(data);
    return new DataView(uint8.buffer).getInt16(0);
}

var float = parseFloat(kafkaDecodeNumber( 'D6A=' )).toFixed(38) / 100;
console.log(float);

float = parseFloat(kafkaDecodeNumber( '/w==' )).toFixed(38) / 100;
console.log(float);

实际上,因为代码只会得到一个编码的 int16 - 代码要简单得多

var kafkaDecodeNumber = function(base64EncodedNumber) {
    const [a, b] = atob(base64EncodedNumber).split('').map(v => v.charCodeAt(0));
    return b === undefined ? a : a * 256 + b;
    
}

var float = parseFloat(kafkaDecodeNumber( 'D6A=' )).toFixed(38) / 100;
console.log(float);

float = parseFloat(kafkaDecodeNumber( '/w==' )).toFixed(38) / 100;
console.log(float);

实际上,只是想出了最简单的方法,因为你只会得到一个 16 位的数字传入 - 而且这种方法不需要任何 base64 填充

var kafkaDecodeNumber = function(base64EncodedNumber) {
    const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    
    const bits = base64EncodedNumber
      .replace(/=+$/g, '')
      .split('')
      .reduce((a, b) => a + b64.indexOf(b).toString(2).padStart(6, '0'), '');
      
    return parseInt(bits.match(/[01]{8}/g).join('').padStart(16, '0'), 2);
}

var float = parseFloat(kafkaDecodeNumber( 'D6A=' )).toFixed(38) / 100;
console.log(float);

float = parseFloat(kafkaDecodeNumber( '/w==' )).toFixed(38) / 100;
console.log(float);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-23
    • 1970-01-01
    • 1970-01-01
    • 2020-01-24
    • 2020-09-25
    • 2017-04-04
    • 1970-01-01
    相关资源
    最近更新 更多