Steganografi huruf ganda

19

Steganografi menyembunyikan pesan yang diberikan di dalam pembawa yang diberikan, menghasilkan paket yang tidak terlihat mencurigakan. Untuk tantangan ini, Anda akan menulis sebuah program yang mengambil pesan ASCII dan operator ASCII sebagai input, dan mengembalikan atau mencetak paket yang identik dengan operator kecuali karakter yang terkait dengan pesan tersebut digandakan, dalam urutan yang sama ketika muncul di pesan.

Aturan:

  1. Jika operator sudah berisi urutan karakter yang sama lebih dari sekali, dan mereka tidak digunakan untuk menyandikan karakter pesan, program akan menguranginya menjadi satu karakter.
  2. Jika operator tidak berisi karakter pesan dalam urutan yang benar, program mungkin tidak menghasilkan apa-apa, operator itu sendiri, atau kesalahan.
  3. Anda dapat mengasumsikan bahwa pesan dan operator adalah string ASCII yang tidak kosong.
  4. Masalah huruf besar: A tidak setara dengan a.
  5. Ketika lebih dari satu paket valid, program Anda dapat menampilkan salah satu atau semuanya.
  6. Ruang adalah karakter seperti karakter lainnya.

Kasus uji:

Paket Pengangkut Pesan
"Hai," "sudah sampai?" "Apakah dia baru saja berubah?" ATAU "Apakah ini terjadi?"
"Tuan," "sudah sampai?" "Apa aku sudah sampai?"
"foo" "sudah tiba?" "" ATAU "sudah tiba?" ATAU kesalahan.
"Mobil" "Kucing itu keren." "CCaats arre col."
"mobil" "Kucing itu keren." "" ATAU "Kucing itu keren." ATAU kesalahan.
"Sofa" "Sofa" "CCoouucchh"
"oo" "oooooooooo" "oooo"
"o o" "oooo oooa" "oo ooa"

Ini adalah kode golf, byte paling sedikit menang.

jkpate
sumber
5
Sama sekali tidak mencurigakan ...: P
Quintec
Apakah "oooo oa"(dengan 2 spasi) output yang valid untuk test case terakhir?
Arnauld
3
Ini bukan output yang valid karena urutan karakter yang digandakan dalam paket harus sesuai dengan urutan karakter dalam pesan. Dalam pesan tersebut, kami memiliki tanda 'o', lalu '', lalu 'o', tetapi paket Anda memiliki ruang setelah o
jkpate
Ah ya, itu masuk akal.
Arnauld
1
Tidak. Alasan saya di balik aturan ini adalah bahwa keluaran program jika tidak ada solusi harus jelas bahwa tidak ada solusi yang mungkin. Tiga keluaran yang diizinkan tidak ambigu, tetapi pemeriksaan yang lebih luas akan diperlukan untuk kasus deduplicated.
jkpate

Jawaban:

5

Jelly , 28 byte

ẹⱮŒp<ƝẠ$ƇṪ
nƝ+çṬ¥a⁸ḟ0Ḥç¦ð¹ç?

Program penuh mengambil carrierdan messagesebagai argumen baris perintah yang mencetak hasilnya
(Untuk paket yang tidak dapat messagedicetak, tidak berubah carrier).

Cobalah online! Atau lihat test-suite .

Bagaimana?

ẹⱮŒp<ƝẠ$ƇṪ - Link 1, helper function to find the indices to double: carrier, message
           -                               e.g. "programming", "rom"
 Ɱ         - map across message with:
ẹ          -   indices of                       [[2,5], [3], [7,8]]
  Œp       - Cartesian product                  [[2,3,7],[2,3,8],[5,3,7],[5,3,8]]
        Ƈ  - filter keep if:
       $   -   last two links as a monad:
     Ɲ     -     for neighbours:
    <      -       less than?                    [1,1]   [1,1]   [0,1]   [0,1]
      Ạ    -     all truthy?                     1       1       0       0
           -                                    [[2,3,7],[2,3,8]]
         Ṫ - tail (if empty yields 0)                    [2,3,8]

nƝ+çṬ¥a⁸ḟ0Ḥç¦ð¹ç? - Main Link: carrier, message
                ? - if...
               ç  - ...condition: last Link (the helper function) as a dyad
             ð    - ...then: perform the dyadic chain to the left (described below)
              ¹   - ...else: do nothing (yields carrier)
                  - (the then clause:)
 Ɲ                - for neighbours in the carrier
n                 - not equal?
     ¥            - last two links as a dyad:
   ç              -   call last Link (the helper function) as a dyad
    Ṭ             -   untruth (e.g. [2,5] -> [0,1,0,0,1])
  +               - add (vectorises)
      a⁸          - logical AND with carrier
        ḟ0        - filter out zeros
            ¦     - sparse application...
           ç      - ...to indices: call last Link (the helper function) as a dyad
          Ḥ       - ...do: double (e.g. 'x' -> 'xx')
Jonathan Allan
sumber
3

JavaScript (ES6), 71 byte

Mengambil input sebagai (message)(carrier).

s=>g=([c,...C],p)=>c?(c==s[0]?(s=s.slice(1),c)+c:p==c?'':c)+g(C,c):s&&X

Cobalah online!


Versi alternatif, 66 byte

Jika kita dapat menerima pesan sebagai array karakter:

s=>g=([c,...C],p)=>c?(c==s[0]?s.shift()+c:p==c?'':c)+g(C,c):s+s&&X

Cobalah online!


Sunting : Terima kasih kepada @tsh karena memperhatikan bahwa saya lupa menghapus beberapa kode ketika beralih dari versi non-rekursif ke rekursif.

Arnauld
sumber
Anda dapat menghapus p=karena p dilewatkan oleh parameter.
tsh
@tsh Ups. Ini beberapa kode sisa dari versi sebelumnya, non-rekursif yang saya lupa hapus. Terima kasih!
Arnauld
2

Haskell, 124 121 107 101 97 95 90 byte

(#).(++"ü")
"ü"#[]=[]
p@(m:n)#e@(c:d)|m/=c=c:p#snd(span(==c)d)|m==n!!0=m:m:n#d|1<2=m:n#e

Meningkatkan pengecualian "Pola non-lengkap" jika operator tidak mengandung pesan.

Cobalah online!

Sunting: -5 byte terima kasih kepada @Laikoni.

nimi
sumber
Saya pikir mengganti kasing memungkinkan Anda untuk melepas m==c: Coba online!
Laikoni
1

Retina 0.8.2 , 67 byte

+`(.)(\1*)\1*(.*¶)(?(\1)(\1(\2)))(.*)$(?!¶)
$1$4$5¶$3$6
M!s`.*¶$
¶

Cobalah online! Membawa operator di baris pertama dan pesan di baris kedua. Penjelasan:

+`(.)(\1*)\1*(.*¶)(?(\1)(\1(\2)))(.*)$(?!¶)
$1$4$5¶$3$6

Proses berjalan dari 1 atau lebih karakter identik dari operator. Jika ada juga menjalankan 1 atau lebih dari karakter yang sama dalam pesan, kemudian menambahkan lebih pendek dari dua berjalan ke output dalam rangkap dua, jika tidak menambahkan satu karakter pembawa ke output. Setiap rangkaian karakter keluaran diakhiri dengan baris baru untuk membedakannya dari input. Pada (?!¶)akhirnya mencegah regex dari berpikir pembawa adalah pesan setelah pesan habis, karena biasanya $diperbolehkan untuk mencocokkan mana yang ¶$akan cocok.

M!s`.*¶$

Hapus semua jika pesan tidak sepenuhnya dikodekan.

Hapus baris baru dari output.

Neil
sumber
Saya pikir itu tidak lulus uji kasus kedua hingga terakhir (yang, jujur ​​saja, saya tidak memiliki dalam posting awal).
jkpate
@ jkpate Terima kasih telah menunjukkannya; Saya harus menulis ulang pendekatan saya sedikit.
Neil
0

Bersih , 118 byte

import StdEnv,StdLib
$[][]=[]
$[u:v]b#(_,w)=span((==)u)v
|b%(0,0)==[u]=[u,u: $if(v%(0,0)<>b%(1,1))w v(tl b)]=[u: $w b]

Cobalah online!

Mengambil operator terlebih dahulu, lalu pesan.

Kesalahan dengan Run time error, rule '$;2' in module 'main' does not matchjika pesan tidak sesuai.

Suram
sumber
0

Ruby , 73 byte

f=->m,c,b=p{x,*c=c;x ?(x==m[0]?x+m.shift: x==b ?'':x)+f[m,c,x]:m[0]?x:''}

Cobalah online!

Fungsi rekursif, mengambil input sebagai array karakter.

Untuk kali ini saya berharap untuk menggunakan squeezemetode built-in Ruby yang mengontrak run berturut-turut dari karakter yang sama menjadi satu instance. Tapi sayangnya, tidak - dua test case yang terakhir mengacaukan segalanya, sehingga saya harus menggunakan pendekatan yang sama sekali berbeda, dan ini ternyata pada dasarnya merupakan pelabuhan jawaban Arnauld .

Kirill L.
sumber
0

Powershell, 134 byte

param($m,$c)$c-csplit"([$m])"|%{$i+=$o=$_-ceq$m[+$i]
if($o-or$_-cne"`0$h"[-1]){$h+=($_-replace'(.)(?=\1)')*($o+1)}}
$h*!($i-$m.Length)

Script mengembalikan empty stringjika pembawa tidak berisi karakter pesan dalam urutan yang benar.

Skrip uji yang kurang golf:

$f = {

param($message,$carrier)
$carrier-csplit"([$message])"|%{                # split by chars of the message, chars itself included ([])
    $offset=$_-ceq$message[+$i]                 # 0 or 1 if current substring is a current message char (case-sensitive equality)
    $i+=$offset                                 # move to next message char if need it
    if($offset-or$_-cne"`0$h"[-1]){             # condition to remove redundant doubles after message char: arrrived -> arrived, ooo -> oo, etc
                                                # `0 to avoid exception error if $h is empty
        $h+=($_-replace'(.)(?=\1)')*($offset+1) # accumulate a double message char or a single substring without inner doubles: arried -> arived, anna -> ana, etc
    }
}
$h*!($i-$message.Length)                        # repeat 0 or 1 times to return '' if the carrier does not contain the message characters in the right order

}

@(
    ,('hi'         ,'has it arrived?'    ,'hhas iit arived?', 'hhas it ariived?')
    ,('hi?'        ,'has it arrived?'    ,'hhas iit arived??', 'hhas it ariived??')
    ,('sir'        ,'has it arrived?'    ,'hass iit arrived?')
    ,('foo'        ,'has it arrived?'    ,'')
    ,('Car'        ,'Cats are cool.'     ,'CCaats arre col.')
    ,('car'        ,'Cats are cool.'     ,'')
    ,('Couch'      ,'Couch'              ,'CCoouucchh')
    ,('oo'         ,'oooooooooo'         ,'oooo')
    ,('o o'        ,'oooo oooa'          ,'oo  ooa')
    ,('er'         ,'error'              ,'eerorr', 'eerror')
    ,('a+b'        ,'anna+bob'           ,'aana++bbob')
) | % {
    $message,$carrier,$expected = $_
    $result = &$f $message $carrier
    "$($result-in$expected): $result"
}

Keluaran:

True: hhas iit arived?
True: hhas iit arived??
True: hass iit arrived?
True:
True: CCaats arre col.
True:
True: CCoouucchh
True: oooo
True: oo  ooa
True: eerror
True: aana++bbob
mazzy
sumber
0

C (gcc) , 69 + 12 = 81 byte

g(char*m,char*_){for(;*_;++_)*m-*_?_[-1]-*_&&p*_):p p*m++));*m&&0/0;}

Kompilasi dengan (12 byte)

-Dp=putchar(

Cobalah online!

g(char*m,char*_){
    for(;*_;++_)        //step through _
        *m-*_?          //check if character should be encoded
            _[-1]-*_&&  //no? skip duplicates
                p*_)    //    print non-duplicates
        :p p*m++));     //print encoded character twice
    *m&&0/0;            //if m is not fully encoded, exit via Floating point exception
}
attinat
sumber