GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie kann ich zweiwertige Textdaten in Binärdaten umwandeln (Bit-Darstellung)

Ein weiteres Perl:

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

Beweis:

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

Das obige liest die Eingabe zeilenweise. Es liegt an Ihnen, sicherzustellen, dass die Linien genau so sind, wie sie sein sollen.

Bearbeiten: Die umgekehrte Operation:

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

Dies liest jeweils ein Byte der Eingabe.

Änderung 2: Einfachere Umkehroperation:

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

Das obige liest jeweils 3 Bytes aus STDIN (aber Empfang von EOF mitten in einer Sequenz ist kein fatales Problem).


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

Mit der folgenden Aussage hat @lcd047 meinen früheren Zustand der Verwirrung ziemlich gut auf den Punkt gebracht:

Sie scheinen von der Ausgabe von od verwirrt zu sein . Verwenden Sie od -tx1 Bytes anschauen. od -x liest Wörter und auf Little-Endian-Maschinen, die Bytes tauschen. Ich habe den obigen Austausch nicht genau verfolgt, aber ich denke, Ihre ursprüngliche Version war korrekt, und Sie müssen sich überhaupt nicht mit der Byte-Reihenfolge herumschlagen. Verwenden Sie einfach od -tx1 , nicht od -x .

Jetzt fühle ich mich sehr besser - die frühere Notwendigkeit für dd conv=swab hat mich den ganzen Tag genervt. Ich konnte es nicht festnageln, aber ich wusste, dass etwas damit nicht stimmte. Es in meiner eigenen Dummheit wegerklären zu können, ist sehr beruhigend - zumal ich etwas gelernt habe.

Wie auch immer, das löscht jedes Byte, das nicht [AB] ist , dann tr Fügen Sie diese an [01] an entsprechend vor fold den resultierenden Stream mit 24 Bytes pro Zeile. dc ? liest Zeile für Zeile, prüft, ob die Eingabe etwas enthält, und wenn ja, P gibt den Byte-Wert dieser Zahl nach stdout aus.

Ab man dc :

  • P

    • Hält den Wert ganz oben auf dem Stapel. Wenn es sich um einen String handelt, wird er einfach ohne abschließenden Zeilenumbruch ausgegeben. Andernfalls handelt es sich um eine Zahl, und der ganzzahlige Teil ihres Absolutwerts wird als "Basis (UCHAR_MAX+1 )" Byte-Stream.
  • i

    • Entfernt den Wert von der Spitze des Stapels und verwendet ihn, um den Eingaberadix festzulegen.

etwas Shell-Automatisierung

Hier ist eine Shell-Funktion, die ich basierend auf dem oben Gesagten geschrieben habe und die in beide Richtungen gehen kann:

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
)

Dadurch wird ABABABA übersetzt Zeug zu Bytes mit -B , also können Sie einfach Folgendes tun:

ABdc -B <infile

Aber es übersetzt beliebige Eingaben in 24 ABABABA Bit-pro-Byte codierte Zeichenfolgen - in der gleichen Form wie beispielsweise in der Frage dargestellt - mit -B .

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

AABBAAABAAAABABAAABBAABA
AAAABABAAABBAABBAAAABABA
AABBABAAAAAABABAAABBABAB
AAAABABAAAAAAAAAAAAAAAAA
1
2
3
4
5

Für -A Ausgabe Ich rollte in cut , expand , und od hier, worauf ich gleich noch eingehen werde, aber ich habe auch noch einen weiteren dc hinzugefügt . Ich habe Zeile für Zeile ? weggelassen lesen Sie dc Skript für eine andere Methode, die ein Array gleichzeitig mit f bearbeitet - Dies ist ein Befehl, der den f druckt Voll dc Befehlsstapel nach stdout. Natürlich, weil dc ist ein Stack-orientiertes last-in, first-out Art der Anwendung, das bedeutet, dass der f ull-stack wird in der umgekehrten Reihenfolge ausgegeben, in der er eingegeben wurde.

Dies könnte ein Problem sein, aber ich verwende einen anderen dc sowieso mit einem o Ausgaberadix auf 100000000 gesetzt um das ganze 0-Padding so einfach wie möglich zu handhaben. Und wenn es das last-in, first-out des anderen liest Stream, es wendet diese Logik noch einmal darauf an, und es kommt alles in der Wäsche heraus. Die beiden dc s arbeiten wie folgt zusammen:

{   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 

...der Stream nach dem ersten 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

...pro Sekunde tee , wie von dc geschrieben zu 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.

...und die Ausgabe des zweiten dc schreibt ist...

 01110011
 01101111
 01101101
 01100101
 00100000
 01100100
 01100001
 01110100
 01100001
 00001010

Von dort die Funktion paste s es auf ...

 01110011    01101111    01101101
 01100101    00100000    01100100
 01100001    01110100    01100001
 00001010

...expand s in Leerzeichen in 10-Spalten-Intervallen...

 01110011  01101111  01101101
 01100101  00100000  01100100
 01100001  01110100  01100001
 00001010

...cut s entfernt alle außer Bytes 2-9,12-19,22-29 ...

011100110110111101101101
011001010010000001100100
011000010111010001100001
00001010

...und tr fügt und Nullen an A an und Einsen an B ...

ABBBAABBABBABBBBABBABBAB
ABBAABABAABAAAAAABBAABAA
ABBAAAABABBBABAAABBAAAAB
AAAABABAAAAAAAAAAAAAAAAA

In der letzten Zeile können Sie meine Hauptmotivation für die Aufnahme von expand sehen - Es ist ein so leichter Filter und stellt sehr einfach sicher, dass jede geschriebene Sequenz - auch die letzte - auf 24 codierte Bits aufgefüllt wird. Wenn dies umgekehrt wird, werden die Zeichenfolgen zu -B decodiert yte-Wert gibt es zwei angehängte NULs:

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

...wie Sie sehen können...

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

Daten aus der realen Welt

Ich habe damit gespielt und es mit einigen einfachen, realistischen Streams ausprobiert. Ich habe diese aufwendige Pipeline für gestaffelte Berichte erstellt...

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

Allerdings habe ich hier keine gute Grundlage für einen Leistungsvergleich. Ich kann nur sagen, dass ich zu diesem Test getrieben wurde, als ich (vielleicht naiv) war beeindruckt genug, um dies zu tun von...

man man | ABdc -A | ABdc -B

...die meinen Terminalbildschirm mit man gemalt haben 's Ausgabe mit der gleichen wahrnehmbaren Geschwindigkeit, wie es der ungefilterte Befehl tun könnte. Die Ausgabe des Tests war...

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

Erste Tests

Der Rest ist nur ein einfacher Proof of Concept, dass es überhaupt funktioniert...

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. Wie kann ich CentOS in CloudLinux OS konvertieren?

  2. Wie können wir ein anderes Passwort als Klartext speichern?

  3. Wie kann man unter Linux Binärdateien von Textdateien unterscheiden?

  4. Wie kann ich einen Dateizeiger ( FILE* fp ) in einen Dateideskriptor (int fd) umwandeln?

  5. Konvertieren Sie Binärdaten in einem Shell-Skript in Hexadezimalzahlen

So zeigen Sie Daten aus einer Textdatei in Linux an

Bash-Scripting:So schreiben Sie Daten in Textdateien

Bash-Scripting:So lesen Sie Daten aus Textdateien

So konvertieren Sie Textdokumente in Sprache auf Ubuntu mit eSpeak

Wie kann ich den gesamten Text in einem PDF rastern?

Wie kann ich eine Binärdatei aus einer .py-Datei erhalten?