Сериализация BitSet или логического массива с Java на Base64 на Python - PullRequest
0 голосов
/ 11 сентября 2018

Мне нужно получить большие логические массивы или BitSets из 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

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

Если:

  • максимальный установленный бит "достаточно мал".
  • и данные, которые вы хотите кодировать, не сильно меняются по размеру.

.. тогда один из подходов может быть:

  • Установить максимальный (+ min) значащий бит (с в 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 голосов
/ 11 сентября 2018

Теперь я меняю биты в каждом байте, используя 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)

Это работает, но есть ли метод, который не требует, чтобы я возился с битами?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...