Najlepszy sposób na zakodowanie bardzo długiego ciągu znaków binarnych do odwracalnej prostej postaci za pomocą Pythona?
-------------------------- 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
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.
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, zlib
kompresja 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()))
Jeśli liczba 0
i 1
jest znacząca inna niż możesz użyć kodowania wyliczeniowego, aby uzyskać najkrótszą reprezentację
Jeśli ciąg składa się tylko z cyfr 0
i 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.