GNU/Linux >> Tutoriels Linux >  >> Linux

Comment puis-je convertir des données textuelles à deux valeurs en binaire (représentation binaire)

Un autre perl :

perl -pe 'BEGIN { binmode \*STDOUT } chomp; tr/AB/\0\1/; $_ = pack "B*", $_'

Preuve :

$ echo ABBBAAAABBBBBABBABBBABBB | \
    perl -pe 'BEGIN { binmode \*STDOUT } chomp; tr/AB/\0\1/; $_ = pack "B*", $_' | \
    od -tx1
0000000 70 fb 77
0000003

Ce qui précède lit l'entrée une ligne à la fois. C'est à vous de vous assurer que les lignes sont exactement ce qu'elles sont censées être.

Modifier : L'opération inverse :

#!/usr/bin/env perl

binmode \*STDIN;

while ( defined ( $_ = getc ) ) {
    $_ = unpack "B*";
    tr/01/AB/;
    print;
    print "\n" if ( not ++$cnt % 3 );
}
print "\n" if ( $cnt % 3 );

Cela lit un octet d'entrée à la fois.

Modification 2 : Opération inverse plus simple :

perl -pe 'BEGIN { $/ = \3; $\ = "\n"; binmode \*STDIN } $_ = unpack "B*"; tr/01/AB/'

Ce qui précède lit 3 octets à la fois à partir de STDIN (mais recevant EOF au milieu d'une séquence n'est pas un problème fatal).


{   printf '2i[q]sq[?z0=qPl?x]s?l?x'
    tr -dc AB | tr AB 01 | fold -b24
}   <infile   | dc

En faisant la déclaration suivante, @lcd047 a assez bien identifié mon état de confusion antérieur :

Vous semblez confus par la sortie de od . Utilisez od -tx1 pour regarder les octets. od -x lit les mots, et sur les petites machines endian qui échange des octets. Je n'ai pas suivi de près l'échange ci-dessus, mais je pense que votre version initiale était correcte et que vous n'avez pas du tout besoin de vous soucier de l'ordre des octets. Utilisez simplement od -tx1 , pas od -x .

Maintenant, cela me fait me sentir beaucoup mieux - le besoin antérieur de dd conv=swab m'a embêté toute la journée. Je ne pouvais pas l'épingler, mais je savais qu'il y avait quelque chose qui n'allait pas. Être capable de l'expliquer dans ma propre stupidité est très réconfortant - surtout depuis que j'ai appris quelque chose.

Quoi qu'il en soit, cela supprimera tous les octets qui ne sont pas [AB] , puis tr traduisez-les en [01] en conséquence, avant fold ing le flux résultant à 24 octets par ligne. dc ? lit une ligne à la fois, vérifie si l'entrée contient quelque chose et, si c'est le cas, P imprime la valeur en octets de ce nombre sur stdout.

À partir de man dc :

  • P

    • Supprime la valeur en haut de la pile. S'il s'agit d'une chaîne, elle est simplement imprimée sans retour à la ligne. Sinon, c'est un nombre, et la partie entière de sa valeur absolue est imprimée en tant que "base (UCHAR_MAX+1 )" flux d'octets.
  • i

    • Supprime la valeur du haut de la pile et l'utilise pour définir la base d'entrée.

une certaine automatisation du shell

Voici une fonction shell que j'ai écrite sur la base de ce qui précède et qui peut aller dans les deux sens :

ABdc()( HOME=/dev/null  A='[fc[fc]]sp[100000000o]p2o[fc]' B=2i
        case    $1      in
        (-B) {  echo "$B"; tr AB 01      | paste -dP - ~      ; }| dc;;
        (-A) {  echo "$A"; od -vAn -tu1  | paste -dlpx - ~ ~ ~; }| dc|
         dc  |  paste - - - ~            | expand -t10,20,30     |
                cut -c2-9,12-19,22-29    | tr ' 01' AAB         ;;
        (*)     set '' "$1";: ${1:?Invalid opt: "'$2'"}         ;;
        esac
)

Cela traduira le ABABABA trucs en octets avec -B , vous pouvez donc simplement faire :

ABdc -B <infile

Mais cela traduira une entrée arbitraire en 24 ABABABA chaînes codées bit par octet - sous la même forme que celle présentée par exemple dans la question - avec -B .

seq 5 | ABdc -A | tee /dev/fd/2 | ABdc -B

AABBAAABAAAABABAAABBAABA
AAAABABAAABBAABBAAAABABA
AABBABAAAAAABABAAABBABAB
AAAABABAAAAAAAAAAAAAAAAA
1
2
3
4
5

Pour -A sortie j'ai roulé en cut , expand , et od ici, que j'aborderai dans une minute, mais j'ai aussi ajouté un autre dc . J'ai laissé tomber le ? ligne pour ligne lire dc script pour une autre méthode qui travaille un tableau à la fois avec f - qui est une commande qui imprime le f Complétez dc commande-pile à stdout. Bien sûr, car dc est un dernier entré, premier sorti orienté pile type d'application, cela signifie que le f ull-stack sort dans l'ordre inverse dans lequel il est entré.

Cela peut être un problème, mais j'utilise un autre dc de toute façon avec un o base de sortie définie sur 100000000 pour gérer tout le 0-padding aussi simplement que possible. Et quand il lit le dernier entré, premier sorti de l'autre flux, il applique à nouveau cette logique, et tout sort dans le lavage. Les deux dc s travaillent de concert comme ceci :

{   echo '[fc[fc]]sp[100000000o]p2o[fc]'
    echo some data | 
    od -An -tu1        ###arbitrary input to unsigned decimal ints
    echo lpx           ###load macro stored in p and execute
} | tee /dev/fd/2  |   ###just using tee to show stream stages
dc| tee /dev/fd/2  |dc 

...le flux par le premier tee ...

[fc[fc]]sp[100000000o]pc2o[fc]            ###dc's init cmd from 1st echo
 115 111 109 101  32 100  97 116  97  10  ###od's output
lpx                                       ###load p; execute

...par seconde tee , comme écrit à partir de dc à dc ...

100000000o                             ###first set output radix
1010                                   ###bin/rev vs of od's out
1100001                                ###dc #2 reads it in, revs and pads it 
1110100                                
1100001
1100100
100000
1100101
1101101
1101111                                ###this whole process is repeated
1110011                                ###once per od output line, so
fc                                     ###each worked array is 16 bytes.

...et la sortie que le second dc écrit est...

 01110011
 01101111
 01101101
 01100101
 00100000
 01100100
 01100001
 01110100
 01100001
 00001010

De là la fonction paste c'est sur ...

 01110011    01101111    01101101
 01100101    00100000    01100100
 01100001    01110100    01100001
 00001010

...expand s en espaces à intervalles de 10 colonnes...

 01110011  01101111  01101101
 01100101  00100000  01100100
 01100001  01110100  01100001
 00001010

...cut s loin de tous sauf octets 2-9,12-19,22-29 ...

011100110110111101101101
011001010010000001100100
011000010111010001100001
00001010

...et tr traduit les et les zéros en A et ceux à B ...

ABBBAABBABBABBBBABBABBAB
ABBAABABAABAAAAAABBAABAA
ABBAAAABABBBABAAABBAAAAB
AAAABABAAAAAAAAAAAAAAAAA

Vous pouvez voir sur la dernière ligne ma principale motivation pour inclure expand - c'est un filtre si léger, et il garantit très facilement que chaque séquence écrite - même la dernière - est complétée à 24 bits codés. Lorsque ce processus est inversé et que les chaînes sont décodées en -B yte-value, il y a deux NUL ajoutés :

ABdc -B <<\IN | od -tc
ABBBAABBABBABBBBABBABBAB
ABBAABABAABAAAAAABBAABAA
ABBAAAABABBBABAAABBAAAAB
AAAABABAAAAAAAAAAAAAAAAA
IN

...comme vous pouvez le voir...

0000000   s   o   m   e       d   a   t   a  \n  \0  \0
0000014

données du monde réel

J'ai joué avec et essayé avec des flux simples et réalistes. J'ai construit ce pipeline élaboré pour les rapports par étapes...

{                            ###dunno why, but I often use man man
    (                        ###as a test input source
        {   man man       |  ###streamed to tee
            tee /dev/fd/3 |  ###branched to stdout
            wc -c >&2        ###and to count source bytes
        }   3>&1          |  ###the branch to stdout is here
        ABdc -A           |  ###converted to ABABABA
        tee /dev/fd/3     |  ###branched again
        ABdc -B              ###converted back to bytes
        times >&2            ###the process is timed
    ) | wc -c >&2            ###ABdc -B's output is counted
} 3>&1| wc -c                ###and so is the output of ABdc -A

Je n'ai pas de bonne base pour la comparaison des performances, ici, cependant. Je peux seulement dire que j'ai été conduit à ce test quand j'étais (peut-être naïvement) assez impressionné pour le faire par...

man man | ABdc -A | ABdc -B

...qui a peint l'écran de mon terminal avec man à la même vitesse perceptible que la commande non filtrée pourrait le faire. Le résultat du test était...

37595                       ###source byte count
0m0.000000s 0m0.000000s     ###shell processor time nil
0m0.720000s 0m0.250000s     ###shell children's total user, system time
37596                       ###ABdc -B output byte count
313300                      ###ABdc -A output byte count

tests initiaux

Le reste n'est qu'une preuve de concept plus simple que cela fonctionne du tout...

printf %s ABBBAAAABBBBBABBABBBABBB|
tee - - - - - - - -|
tee - - - - - - - - - - - - - - - |
{   printf '2i[q]sq[?z0=qPl?x]s?l?x'
    tr -dc AB | tr AB 01 | fold -b24
} | dc        | od -tx1
0000000 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70
0000020 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb
0000040 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77
0000060 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70
0000100 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb
0000120 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77
0000140 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70
0000160 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb
0000200 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77
0000220 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70
0000240 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb
0000260 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77
0000300 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70
0000320 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb
0000340 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77
0000360 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70
0000400 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb
0000420 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77
0000440 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70
0000460 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb
0000500 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77
0000520 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70
0000540 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb
0000560 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77
0000600 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70
0000620 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb
0000640 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77 70 fb 77
0000660


Linux
  1. Comment puis-je convertir CentOS en système d'exploitation CloudLinux ?

  2. Comment pouvons-nous stocker un mot de passe autre que du texte brut ?

  3. Comment distinguer le binaire des fichiers texte sous Linux

  4. Comment puis-je convertir un pointeur de fichier ( FILE* fp ) en un descripteur de fichier (int fd) ?

  5. Convertir des données binaires en hexadécimal dans un script shell

Comment afficher les données d'un fichier texte sous Linux

Script bash :comment écrire des données dans des fichiers texte

Script bash :comment lire des données à partir de fichiers texte

Comment convertir un document texte en discours sur Ubuntu à l'aide d'eSpeak

Comment puis-je justifier du texte brut sous Linux?

Comment pixelliser tout le texte d'un PDF ?