Najlepszy sposób na zakodowanie bardzo długiego ciągu znaków binarnych do odwracalnej prostej postaci za pomocą Pythona?

Jan 13 2021

-------------------------- Dodaj nowe---------------------- -------

Tutaj uzupełnię więcej informacji:

W rzeczywistości mam to LONG STRING w środowisku-A i muszę go skopiować i wkleić do środowiska-B;

NIEZWYKLE, envir-A i envir-B nie są połączone (brak wzajemnego dostępu), więc myślę o sposobie kodowania / dekodowania, aby to przedstawić, w przeciwnym razie dla większej liczby plików muszę ręcznie wprowadzić ciąg --- -co jest powolne i nie powtarzalne.

Jakieś sugestie lub zalecenia dotyczące gadżetów? Wielkie dzięki!


Mam dziwny problem z zakodowaniem SUPER LONG plików binarnych do prostej postaci, na przykład kilku cyfr.

Powiedzmy, że istnieje długi ciąg składający się tylko z 1 i 0, np. „110 ... 011” o długości od 1000 do 100 000 lub nawet więcej cyfr, i chciałbym zakodować ten ŁAŃCUCH na coś, co ma mniej cyfr / znaków. Następnie muszę przywrócić go z powrotem do oryginalnego STRING.

Obecnie próbuję użyć metody hex / int w Pythonie, aby „skompresować” ten ciąg i „zdekompresować” go z powrotem do pierwotnej postaci.

Przykładem może być:

1. ciąg wejściowy: '110011110110011'

'' '

def Bi_to_Hex_Int(input_str, method ):

#2to16 
if method=='hex':
    string= str(input_str)
    input_two= string
    result=    hex(int(input_two,2))
    
#2to10 
if method=='int':
    string= str(input_str)
    input_two= string
    result=     int(input_two,2) 


print("input_bi length",len(str(input_two)), "\n output hex length",len(str(result)),'\n method: {}'.format(method) )
return result


res_16 =Bi_to_Hex_Int(gene , 'hex')
=='0x67b3'

res_10 =Bi_to_Hex_Int(gene , 'int')
== 26547

'' '

Następnie mogę to cofnąć:

'' '

def HexInt_to_bi(input_str , method):


if method =='hex':

    back_two =  bin(int(input_str,16))

    back_two =  back_two[2:]
    
     
if method =='int':

    back_two =  bin( int(input_str ))

    back_two =  back_two[2:]
    
    
print("input_hex length",len(str(input_str)), "\n output bi length",len(str(back_two)) )
return back_two


hexback_two = HexInt_to_bi(res_16, 'hex')
intback_two = HexInt_to_bi(res_10 , 'int')

'' '

ALE, to ma problem, próbowałem około 500 cyfr String: 101010 ... 0001 (500d), najlepszy wynik „skompresowany” to około 127 cyfr szesnastkowych;

Czy jest więc lepszy sposób na dalsze „skompresowanie” ciągu do mniejszej liczby cyfr?

** Powiedz, że 5000 cyfr łańcucha składa się z jedynek i zer, a następnie skompresuj do 50/100 cyfry / znaki (jeszcze mniejsze) ** ??

Odpowiedzi

1 Som-1 Jan 13 2021 at 19:19

Jeśli chcesz, żeby było tak prosto, powiedzmy, że 1 znak szesnastkowy kompresuje 4 znaki binarne (2 ^ 4 = 16). Żądany współczynnik kompresji wynosi około 100/50 razy. 50 razy potrzebujesz skompresować 50 znaków binarnych do 1 znaku, co oznacza, że ​​potrzebujesz 2 ^ 50 różnych znaków, aby zakodować dowolną kombinację. To całkiem sporo.

Jeśli akceptujesz niższy współczynnik, możesz wypróbować base64, jak opisano tutaj . Jego współczynnik kompresji wynosi 6 do 1.

W przeciwnym razie musisz wymyślić jakiś złożony algorytm, taki jak dzielenie łańcucha na bloki, szukanie podobnych wśród nich, kodowanie ich różnymi symbolami, budowanie mapy tych symboli itp.

Prawdopodobnie łatwiej jest skompresować ciąg za pomocą archiwizatora , a następnie zwrócić reprezentację wyniku w standardzie base64.

Jeśli zadanie na to pozwala, możesz gdzieś przechowywać całe łańcuchy i nadawać im krótkie, unikalne nazwy, więc zamiast kompresji i dekompresji musisz przechowywać i pobierać łańcuchy według nazw.

1 MarkRansom Jan 14 2021 at 01:52

Prawdopodobnie nie tworzy to absolutnie najkrótszego ciągu, jaki można uzyskać, ale jest to banalnie łatwe przy użyciu funkcji wbudowanych w Python. Nie ma potrzeby konwertowania znaków do formatu binarnego, zlibkompresja przekształci dane wejściowe zawierające tylko 2 różne znaki w coś optymalnego.

Kodowanie:

import zlib
import base64
result = base64.b64encode(zlib.compress(input_str.encode()))
1 TThoEinthausend Jan 14 2021 at 04:08

Jeśli liczba 0i 1jest znacząca inna niż możesz użyć kodowania wyliczeniowego, aby uzyskać najkrótszą reprezentację

MarkAdler Jan 14 2021 at 01:32

Jeśli ciąg składa się tylko z cyfr 0i 1, możesz spakować osiem cyfr w jeden bajt. Będziesz także musiał śledzić, ile cyfr jest poza ostatnią wielokrotnością ośmiu, ponieważ ostatni bajt może zawierać mniej niż osiem cyfr.