GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana saya bisa mengonversi data teks dua nilai menjadi biner (representasi bit)

Perl lain:

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

Bukti:

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

Di atas membaca masukan satu baris pada satu waktu. Terserah Anda untuk memastikan garis persis seperti yang seharusnya.

Edit: Operasi sebaliknya:

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

Ini membaca satu byte masukan sekaligus.

Edit 2: Operasi balik yang lebih sederhana:

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

Di atas membaca 3 byte sekaligus dari STDIN (namun menerima EOF di tengah urutan bukanlah masalah yang fatal).


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

Dalam membuat pernyataan berikut, @lcd047 telah cukup memahami keadaan kebingungan saya sebelumnya:

Sepertinya Anda bingung dengan keluaran od . Gunakan od -tx1 untuk melihat byte. od -x membaca kata-kata, dan pada mesin little endian yang bertukar byte. Saya tidak mengikuti dengan cermat pertukaran di atas, tetapi menurut saya versi awal Anda sudah benar, dan Anda tidak perlu mengacaukan urutan byte sama sekali. Cukup gunakan od -tx1 , bukan od -x .

Sekarang ini membuat saya merasa banyak lebih baik - kebutuhan sebelumnya untuk dd conv=swab menggangguku sepanjang hari. Saya tidak bisa menyematkannya, tetapi saya tahu ada sesuatu yang salah dengan itu. Mampu menjelaskannya dengan kebodohan saya sendiri sangat menghibur - terutama karena saya mempelajari sesuatu.

Bagaimanapun, itu akan menghapus setiap byte yang bukan [AB] , lalu tr anslate menjadi [01] karenanya, sebelum fold ing aliran yang dihasilkan pada 24 byte per baris. dc ? membaca satu baris sekaligus, memeriksa apakah input berisi sesuatu, dan, jika demikian, P mencetak nilai byte dari nomor itu ke stdout.

Dari man dc :

  • P

    • Memunculkan nilai di atas tumpukan. Jika itu adalah string, itu hanya dicetak tanpa baris baru. Kalau tidak, itu adalah angka, dan bagian bilangan bulat dari nilai absolutnya dicetak sebagai "base (UCHAR_MAX+1 )" aliran byte.
  • i

    • Memunculkan nilai dari bagian atas tumpukan dan menggunakannya untuk menyetel radix masukan.

beberapa otomatisasi shell

Ini adalah fungsi shell yang saya tulis berdasarkan hal di atas yang bisa berjalan dua arah:

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
)

Itu akan menerjemahkan ABABABA barang ke byte dengan -B , jadi Anda bisa melakukan:

ABdc -B <infile

Tapi itu akan menerjemahkan input sewenang-wenang ke 24 ABABABA string yang disandikan bit per byte - dalam bentuk yang sama seperti yang disajikan misalnya dalam pertanyaan - dengan -B .

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

AABBAAABAAAABABAAABBAABA
AAAABABAAABBAABBAAAABABA
AABBABAAAAAABABAAABBABAB
AAAABABAAAAAAAAAAAAAAAAA
1
2
3
4
5

Untuk -A output saya memasukkan cut , expand , dan od di sini, yang akan saya bahas sebentar lagi, tetapi saya juga menambahkan dc lainnya . Saya membuang baris demi baris ? baca dc skrip untuk metode lain yang berfungsi sebagai array pada waktu dengan f - yang merupakan perintah untuk mencetak f ull dc tumpukan perintah ke stdout. Tentu saja karena dc adalah last-in,first-out yang berorientasi stack jenis aplikasi, artinya f ull-stack keluar dalam urutan terbalik.

Ini mungkin menjadi masalah, tapi saya menggunakan dc yang lain tetap dengan o utput radix diatur ke 100000000 untuk menangani semua 0-padding sesederhana mungkin. Dan ketika membaca last-in,first-out yang lain streaming, itu menerapkan logika itu lagi, dan semuanya keluar begitu saja. Kedua dc s bekerja bersama seperti ini:

{   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 

...streaming per tee pertama ...

[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

...per tee kedua , seperti yang ditulis dari dc ke 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.

...dan keluarannya adalah dc yang kedua menulis adalah...

 01110011
 01101111
 01101101
 01100101
 00100000
 01100100
 01100001
 01110100
 01100001
 00001010

Dari sana fungsi paste ada di ...

 01110011    01101111    01101101
 01100101    00100000    01100100
 01100001    01110100    01100001
 00001010

...expand s ke spasi pada interval 10 kolom...

 01110011  01101111  01101101
 01100101  00100000  01100100
 01100001  01110100  01100001
 00001010

...cut s semua kecuali byte 2-9,12-19,22-29 ...

011100110110111101101101
011001010010000001100100
011000010111010001100001
00001010

...dan tr anslate dan nol menjadi A dan satu ke B ...

ABBBAABBABBABBBBABBABBAB
ABBAABABAABAAAAAABBAABAA
ABBAAAABABBBABAAABBAAAAB
AAAABABAAAAAAAAAAAAAAAAA

Anda dapat melihat pada baris terakhir di sana motivasi utama saya untuk menyertakan expand - ini adalah filter yang sangat ringan, dan sangat mudah memastikan bahwa setiap urutan yang ditulis - bahkan yang terakhir - diisi hingga 24 bit yang disandikan. Saat itu proses dibalik, dan string didekodekan ke -B yte-value, ada dua NUL yang ditambahkan:

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

...seperti yang Anda lihat...

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

data dunia nyata

Saya memainkannya, dan mencobanya dengan aliran yang sederhana dan realistis. Saya membuat pipeline yang rumit ini untuk laporan bertahap...

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

Saya tidak memiliki dasar yang baik untuk perbandingan kinerja, di sini. Saya hanya bisa mengatakan bahwa saya terdorong ke ujian ini ketika saya (mungkin naif) cukup terkesan untuk melakukannya dengan...

man man | ABdc -A | ABdc -B

... yang melukis layar terminal saya dengan man output pada kecepatan yang terlihat sama seperti yang mungkin dilakukan oleh perintah tanpa filter. Keluaran dari tes ini adalah...

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

pengujian awal

Selebihnya hanyalah bukti konsep yang lebih sederhana bahwa itu berfungsi sama sekali...

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. Bagaimana saya bisa Mengonversi CentOS ke CloudLinux OS?

  2. Bagaimana kita bisa menyimpan kata sandi selain teks biasa?

  3. Bagaimana membedakan biner dari file teks di linux

  1. Bagaimana cara mengonversi penunjuk file ( FILE* fp ) menjadi deskriptor file (int fd)?

  2. Bagaimana cara mengonversi data file ke hex biasa?

  3. Bagaimana cara mengubah HTML menjadi teks?

  1. Bagaimana saya bisa menjalankan executable yang tidak dipercaya di linux dengan aman?

  2. mengkonversi file teks dari bit ke file biner

  3. Ubah mode biner ke mode teks dan opsi sebaliknya