Le meilleur moyen d'encoder une très longue chaîne binaire en une forme simple réversible en utilisant Python?
-------------------------- ajouter un nouveau ---------------------- -------
Permettez-moi de remplir plus d'informations ici:
La situation réelle est que j'ai cette LONG STRING dans l'environnement-A, et je dois le copier et le coller dans l'environnement-B;
MALHEUREUSEMENT, envir-A et envir-B ne sont pas connectés (pas d'accès mutuel), donc je pense à un moyen d'encoder / décoder pour le représenter, sinon pour plus de fichiers, je dois saisir la chaîne à la main --- -qui est lent et non reproductible.
Une suggestion ou un gadget à recommander? Merci beaucoup!
Je suis confronté à un problème étrange pour encoder des binaires SUPER LONG sous une forme simple, comme plusieurs chiffres.
Disons qu'il y a une longue chaîne composée de seulement 1 et 0, par exemple "110 ... 011" d'une longueur de 1 000 à 100 000 ou même plus de chiffres, et j'aimerais encoder cette STRING en quelque chose qui a moins de chiffres / caractères. Ensuite, je dois rétablir le STRING d'origine.
Actuellement, j'essaie d'utiliser la méthode hex / int en Python pour 'compresser' cette chaîne et la 'décompresser' à sa forme originale.
Un exemple serait:
1. chaîne d'entrée: '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
'' '
Ensuite, je peux l'inverser:
'' '
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')
'' '
MAIS, cela pose un problème, j'ai essayé environ 500 chiffres de String: 101010 ... 0001 (500d), le meilleur résultat «compressé» est d'environ 127 chiffres par hexadécimal;
Alors, y a-t-il un meilleur moyen de «compresser» davantage la chaîne à moins de chiffres?
** Disons que 5000 chiffres de la chaîne se composent de 1 et de 0, compressez à 50/100 quelque chose de chiffres / caractères (encore plus bas) ** ??
Réponses
Si vous voulez que ce soit aussi simple, disons qu'un caractère hexadécimal compresse 4 caractères binaires (2 ^ 4 = 16). Le taux de compression souhaité est d'environ 100/50 fois. Pour 50 fois, vous avez besoin de 50 caractères binaires à compresser en 1 caractère, ce qui signifie que vous avez besoin de 2 ^ 50 caractères différents pour encoder n'importe quelle combinaison. Beaucoup de choses.
Si vous acceptez un ratio inférieur, vous pouvez essayer base64 comme décrit ici . Son taux de compression est de 6 pour 1.
Sinon, vous devez trouver un algorithme complexe comme diviser votre chaîne en blocs, rechercher des éléments similaires, les encoder avec différents symboles, construire une carte de ces symboles, etc.
Il est probablement plus facile de compresser votre chaîne avec un archivateur , puis de renvoyer une représentation en base64 du résultat.
Si la tâche le permet, vous pouvez stocker les chaînes entières quelque part et leur donner des noms uniques courts, donc au lieu de la compression et de la décompression, vous devez stocker et récupérer les chaînes par noms.
Cela ne produit probablement pas la chaîne la plus courte que vous puissiez obtenir, mais c'est trivialement facile d'utiliser les fonctionnalités intégrées à Python. Pas besoin de convertir les caractères dans un format binaire, la zlib
compression convertira une entrée avec seulement 2 caractères différents en quelque chose de optimal.
Codage:
import zlib
import base64
result = base64.b64encode(zlib.compress(input_str.encode()))
Si le nombre de 0
et 1
est significativement différent de celui, vous pouvez utiliser le codage énumératif pour obtenir la représentation la plus courte
Si la chaîne se compose uniquement de 0
et 1
chiffres, vous pouvez regrouper huit chiffres dans un octet. Vous devrez également garder une trace du nombre de chiffres après le dernier multiple de huit, car le dernier octet peut représenter moins de huit chiffres.