GNU/Linux >> Linux Esercitazione >  >> Linux

Come posso convertire i dati di testo a due valori in binario (rappresentazione in bit)

Un altro perl:

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

Prova:

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

Quanto sopra legge l'input una riga alla volta. Sta a te assicurarti che le linee siano esattamente come dovrebbero essere.

Modifica: L'operazione inversa:

#!/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 );

Questo legge un byte di input alla volta.

Modifica 2: Operazione inversa più semplice:

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

Quanto sopra legge 3 byte alla volta da STDIN (ma ricevendo EOF nel mezzo di una sequenza non è un problema fatale).


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

Facendo la seguente dichiarazione, @lcd047 ha centrato abbastanza bene il mio precedente stato di confusione:

Sembri confuso dall'output di od . Usa od -tx1 per guardare i byte. od -x legge parole e su macchine little endian che scambia byte. Non ho seguito da vicino lo scambio di cui sopra, ma penso che la tua versione iniziale fosse corretta e non devi assolutamente scherzare con l'ordine dei byte. Basta usare od -tx1 , non od -x .

Questo mi fa sentire molto meglio - la precedente necessità di dd conv=swab mi ha infastidito tutto il giorno. Non potevo fissarlo, ma sapevo che c'era qualcosa che non andava. Essere in grado di spiegarlo con la mia stessa stupidità è molto confortante, soprattutto perché ho imparato qualcosa.

Ad ogni modo, questo eliminerà ogni byte che non è [AB] , quindi tr convertili in [01] di conseguenza, prima di fold ing il flusso risultante a 24 byte per riga. dc ? legge una riga alla volta, controlla se l'input conteneva qualcosa e, in tal caso, P invia il valore in byte di quel numero a stdout.

Da man dc :

  • P

    • Estrae il valore in cima allo stack. Se è una stringa, viene semplicemente stampata senza una nuova riga finale. Altrimenti è un numero e la parte intera del suo valore assoluto viene stampata come "base (UCHAR_MAX+1 )" flusso di byte.
  • i

    • Estrae il valore dalla parte superiore dello stack e lo utilizza per impostare la radice di input.

un po' di automazione della shell

Ecco una funzione di shell che ho scritto sulla base di quanto sopra che può andare in entrambe le direzioni:

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
)

Questo tradurrà il ABABABA cose in byte con -B , quindi puoi semplicemente fare:

ABdc -B <infile

Ma tradurrà l'input arbitrario in 24 ABABABA stringhe codificate bit per byte - nella stessa forma di quella presentata ad esempio nella domanda - con -B .

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

AABBAAABAAAABABAAABBAABA
AAAABABAAABBAABBAAAABABA
AABBABAAAAAABABAAABBABAB
AAAABABAAAAAAAAAAAAAAAAA
1
2
3
4
5

Per -A output ho inserito cut , expand e od qui, di cui parlerò tra un minuto, ma ho anche aggiunto un altro dc . Ho eliminato il ? riga per riga leggi dc script per un altro metodo che lavora un array alla volta con f - che è un comando che stampa il f ull dc stack di comandi a stdout. Certo, perché dc è un ultimo entrato, primo uscito orientato allo stack tipo di applicazione, ciò significa che il f ull-stack esce nell'ordine inverso in cui è entrato.

Questo potrebbe essere un problema, ma io uso un altro dc comunque con un o radice di output impostata su 100000000 per gestire tutto lo 0-padding nel modo più semplice possibile. E quando legge il ultimo entrato, primo uscito dell'altro stream, applica di nuovo quella logica e tutto viene fuori nel lavaggio. I due dc Funziona in concerto in questo modo:

{   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 

...il flusso per il primo 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

...al secondo tee , come scritto da dc a 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.

...e l'output che il secondo dc scrive è...

 01110011
 01101111
 01101101
 01100101
 00100000
 01100100
 01100001
 01110100
 01100001
 00001010

Da lì la funzione paste è su ...

 01110011    01101111    01101101
 01100101    00100000    01100100
 01100001    01110100    01100001
 00001010

...expand s a spazi a intervalli di 10 colonne...

 01110011  01101111  01101101
 01100101  00100000  01100100
 01100001  01110100  01100001
 00001010

...cut manca tutto tranne i byte 2-9,12-19,22-29 ...

011100110110111101101101
011001010010000001100100
011000010111010001100001
00001010

...e tr traduce e zeri in A e quelli a B ...

ABBBAABBABBABBBBABBABBAB
ABBAABABAABAAAAAABBAABAA
ABBAAAABABBBABAAABBAAAAB
AAAABABAAAAAAAAAAAAAAAAA

Puoi vedere nell'ultima riga la mia motivazione principale per includere expand - è un filtro così leggero e garantisce molto facilmente che ogni sequenza scritta, anche l'ultima, sia riempita fino a 24 bit codificati. Quando il processo viene invertito e le stringhe vengono decodificate in -B yte-value, ci sono due NUL aggiunti:

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

...come puoi vedere...

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

dati del mondo reale

Ci ho giocato e l'ho provato con alcuni flussi semplici e realistici. Ho costruito questa elaborata pipeline per i report a fasi...

{                            ###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

Non ho alcuna buona base per il confronto delle prestazioni, qui, però. Posso solo dire che sono stato spinto a questa prova quando ero (forse ingenuamente) abbastanza impressionato da farlo da...

man man | ABdc -A | ABdc -B

...che ha dipinto lo schermo del mio terminale con man 's alla stessa velocità riconoscibile come potrebbe fare il comando non filtrato. L'output del test è stato...

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

test iniziali

Il resto è solo una semplice dimostrazione del fatto che funziona...

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. Come posso monitorare i dati su una porta seriale in Linux?

  2. Come posso giustificare il testo normale in Linux?

  3. Come convertire i dati del file in semplice esadecimale?

  4. convertire file di testo di bit in file binario

  5. Converti la modalità binaria in modalità testo e l'opzione inversa

Come visualizzare i dati da un file di testo in Linux

Scripting Bash:come scrivere dati su file di testo

Scripting Bash:come leggere i dati dai file di testo

Come convertire un documento di testo in voce su Ubuntu usando eSpeak

Come posso rasterizzare tutto il testo in un PDF?

Come posso ottenere un binario da un file .py