从Java到从Base64到Python的序列化BitSet或布尔数组

问题描述 投票:1回答:3

我需要通过文本文件将大型的布尔数组或BitSet从Java获取到Python中。理想情况下,我想通过Base64表示形式保持紧凑,但仍可以将值嵌入CSV文件中。 (因此,布尔数组将是CSV文件中的一列。)

但是我在正确对齐字节时遇到问题。我应该在哪里/如何指定正确的字节顺序?

这是一个示例,从执行的意义上说是起作用的,但由于我的位不在我想要的位而不能起作用。

Java:

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.Base64;
import java.util.Base64.Encoder;
import java.util.BitSet;

public class basictest {

    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        Encoder b64 = Base64.getEncoder();
        String name = "name";
        BitSet b = new BitSet();
        b.set(444);
        b.set(777);
        b.set(555);
        byte[] bBytes = b.toByteArray();
        String fp_str = b64.encodeToString(bBytes);
        BufferedWriter w = new BufferedWriter(new FileWriter("out.tsv"));
        w.write(name  + "\t" + fp_str + "\n");
        w.close();
    }

}

Python:

import numpy as np
import base64
from bitstring import BitArray, BitStream ,ConstBitStream
filename = "out.tsv"
with open(filename) as file:
    data = file.readline().split('\t')
b_b64 = data[1]
b_bytes = base64.b64decode(b_b64)
b_bits = BitArray(bytes=b_bytes)

b_bits[444] # False
b_bits[555] # False
b_bits[777] # False
# but
b_bits[556] # True
# it's not shifted:
b_bits[445] # False
java python serialization base64 bitset
3个回答
1
投票

我现在使用https://stackoverflow.com/a/5333563/1259675反转每个字节中的位:

numbits = 8
r_bytes = [
    sum(1<<(numbits-1-i) for i in range(numbits) if b>>i&1)
    for b in b_bytes]
b_bits = BitArray(r_bytes)

这有效,但是有没有一种方法让我自己不喜欢这些位?


0
投票

如果:

  • 要设置的最大位为“足够小”。
  • 并且您要编码的数据大小不会太大变化。

..那么一种方法可以是:

  • 在Java中设置最大(+最小)有效位。
  • 并在python中忽略它们。

,然后c(sh!)可以正常工作而无需字节反转,也无需进一步转换:

// assuming a 1024 bit word
public static final int LEFT_SIGN = 0;
public static final int RIGHT_SIGN = 1025; //choose a size, that fits your needs [0 .. Integer.MAX_VALUE - 1 (<-theoretically)] 

public static void main(String[] args) throws Exception {
    ...
    b.set(LEFT_SIGN);
    b.set(444 + 1);
    b.set(777 + 1);
    b.set(555 + 1);
    b.set(RIGHT_SIGN);
    ...

然后是python:

# as before ..
b_bits[0] # Ignore!
b_bits[445] # True
b_bits[556] # True
b_bits[778] # True
b_bits[1025] # Ignore!;)

您的方便(=编码)将是(最大)“字长” ...及其所有优点和缺点。


0
投票

我们可以将python的bitarray包用于此特定用例。

from bitarray import bitarray
import base64

with open(filename) as file:
    data = file.readline().strip().split('\t')

b_b64 = data[1]
b_bytes = base64.b64decode(b_b64)
bs = bitarray(endian='little')
bs.frombytes(b_bytes)
print bs
© www.soinside.com 2019 - 2024. All rights reserved.