¿La mejor manera de codificar una cadena de binarios muy larga en una forma simple reversible usando Python?

Jan 13 2021

-------------------------- agregar nuevo ---------------------- -------

Déjame completar más información aquí:

La situación real es que tengo esta LARGA CADENA en el entorno-A, y necesito copiarla y pegarla en el entorno-B;

Lamentablemente, envir-A y envir-B no están conectados (no hay acceso mutuo), así que estoy pensando en una forma de codificar / decodificar para representarlo, de lo contrario, para obtener más archivos, tengo que ingresar la cadena a mano --- -que es lento y no reproducible.

¿Alguna sugerencia o gadget recomendado? ¡Muchas gracias!


Me enfrento a un problema extraño para codificar binarios SUPER LARGOS en una forma simple, como varios dígitos.

Digamos que hay una cadena larga que consta de solo 1 y 0, por ejemplo, "110 ... 011" de una longitud de 1,000 a 100,000 o incluso más dígitos, y me gustaría codificar esta STRING en algo que tenga menos dígitos / caracteres. Luego, necesito revertirlo al STRING original.

Actualmente estoy tratando de usar el método hex / int en Python para 'comprimir' esta Cadena y 'descomprimirla' de nuevo a su forma original.

Un ejemplo sería:

1.cadena de entrada: '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

'' '

Entonces puedo revertirlo:

'' '

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')

'' '

PERO, esto tiene un problema, probé alrededor de 500 dígitos de String: 101010 ... 0001 (500d), el mejor resultado 'comprimido' es alrededor de 127 dígitos por hexadecimal;

Entonces, ¿hay una mejor manera de 'comprimir' aún más la cadena a menos dígitos?

** Digamos que 5,000 dígitos de cadena consisten en 1 y 0, comprime a 50/100 algo de dígitos / caracteres (incluso más bajo) ** ??

Respuestas

1 Som-1 Jan 13 2021 at 19:19

Si lo desea así de simple, digamos que 1 carácter hexadecimal comprime 4 caracteres binarios (2 ^ 4 = 16). La relación de compresión que desea es aproximadamente 100/50 veces. Para 50 veces, necesita 50 caracteres binarios para ser comprimidos en 1 carácter, lo que significa que necesita 2 ^ 50 caracteres diferentes para codificar cualquier combinación. Mucho que es.

Si acepta una relación más baja, puede probar base64 como se describe aquí . Su relación de compresión es de 6 a 1.

De lo contrario, debe idear un algoritmo complejo como dividir su cadena en bloques, buscar similares entre ellos, codificarlos con diferentes símbolos, construir un mapa de esos símbolos, etc.

Probablemente sea más fácil comprimir su cadena con un archivador y luego devolver una representación base64 del resultado.

Si la tarea lo permite, puede almacenar las cadenas completas en algún lugar y darles nombres cortos y únicos, por lo que en lugar de compresión y descompresión, debe almacenar y recuperar cadenas por nombres.

1 MarkRansom Jan 14 2021 at 01:52

Esto probablemente no produce la cadena más corta que puede obtener, pero es trivialmente fácil usando las funciones integradas en Python. No es necesario convertir los caracteres a formato binario, la zlibcompresión convertirá una entrada con solo 2 caracteres diferentes en algo óptimo.

Codificación:

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

Si el recuento de 0y 1es significativamente diferente, puede usar la codificación enumerativa para obtener la representación más corta

MarkAdler Jan 14 2021 at 01:32

Si la cadena consta solo de 0y 1dígitos, puede empaquetar ocho dígitos en un byte. También deberá realizar un seguimiento de cuántos dígitos hay después del último múltiplo de ocho, ya que el último byte puede representar menos de ocho dígitos.