Steganografia a doppia lettera


19

La steganografia nasconde un determinato messaggio all'interno di un determinato vettore, producendo un pacchetto che non sembra sospetto. Per questa sfida, si scriverà un programma che accetta come input un messaggio ASCII e un corriere ASCII e si restituirà o stamperà un pacchetto identico al corriere, ad eccezione del fatto che i caratteri corrispondenti al messaggio siano raddoppiati, nello stesso ordine in cui compaiono il messaggio.

Regole:

  1. Se il corriere contiene già sequenze dello stesso carattere più di una volta e non vengono utilizzate per codificare un carattere del messaggio, il programma li ridurrà a un singolo carattere.
  2. Se il corriere non contiene i caratteri del messaggio nel giusto ordine, il programma potrebbe non restituire nulla, il corriere stesso o un errore.
  3. Si può presumere che il messaggio e il corriere siano stringhe ASCII non vuote.
  4. La capitalizzazione è importante: A non equivale a.
  5. Quando è valido più di un pacchetto, il programma può generare uno o tutti loro.
  6. Lo spazio è un personaggio come qualsiasi altro personaggio.

Casi test:

Pacchetto portante messaggi
"ciao" "è arrivato?" "è nato?" O "ha ottenuto?"
"signore" "è arrivato?" "è arrivato?"
"pippo" "è arrivato?" "" O "è arrivato?" O un errore.
"Auto" "I gatti sono fantastici." "CCaats arre col."
"macchina" "I gatti sono fantastici." "" O "I gatti sono fantastici." O un errore.
"Divano" "Divano" "CCoouucchh"
"oo" "oooooooooo" "oooo"
"o o" "oooo oooa" "oo ooa"

Questo è il golf del codice, quindi vince meno byte.


5
Per niente sospetto ...: P
Quintec,

È "oooo oa"(con 2 posti) un'uscita valida per l'ultimo banco di prova?
Arnauld,

3
Non è un output valido perché l'ordine dei caratteri raddoppiati nel pacchetto deve corrispondere all'ordine dei caratteri nel messaggio. Nel messaggio, abbiamo una 'o', quindi una '', quindi una 'o', ma il tuo pacchetto ha lo spazio dopo la o
jkpate

Ah sì, ha senso.
Arnauld,

1
No. Il mio ragionamento alla base di questa regola è che l'output del programma in caso di nessuna soluzione dovrebbe essere inequivocabile che nessuna soluzione è possibile. Le tre uscite consentite sono inequivocabili, ma per il caso deduplicato sarebbe necessario un controllo più approfondito.
jkpate,

Risposte:


5

Gelatina , 28 byte

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

Un programma completo che prende carriere messagecome argomenti da riga di comando che stampa il risultato
(per un non comprimibile messagestampa invariato carrier).

Provalo online! Oppure vedi la suite di test .

Come?

ẹⱮŒ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')

3

JavaScript (ES6), 71 byte

Accetta input come (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

Provalo online!


Versione alternativa, 66 byte

Se possiamo prendere il messaggio come una matrice di caratteri:

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

Provalo online!


Modifica : grazie a @tsh per aver notato che ho dimenticato di rimuovere un po 'di codice quando sono passato dalle versioni non ricorsive a quelle ricorsive.


È possibile rimuovere p=poiché p viene passato da un parametro.
tsh

@tsh Oops. È un codice residuo delle versioni precedenti non ricorsive che ho dimenticato di rimuovere. Grazie!
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

Genera l'eccezione "Schemi non esaustivi" se il corriere non contiene il messaggio.

Provalo online!

Modifica: -5 byte grazie a @Laikoni.


Penso che cambiare caso ti permetta di abbandonare m==c: provalo online!
Laikoni,

1

Retina 0.8.2 , 67 byte

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

Provalo online! Porta il corriere sulla prima riga e il messaggio sulla seconda riga. Spiegazione:

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

Esecuzioni di processo di 1 o più caratteri identici del corriere. Se nel messaggio è presente anche una sequenza di 1 o più caratteri uguali, aggiungere in duplice copia l'output più breve delle due uscite, altrimenti aggiungere un singolo carattere del vettore all'output. Ogni serie di caratteri di output termina con una nuova riga per distinguerla dall'input. Alla (?!¶)fine impedisce alla regex di pensare che il corriere sia il messaggio una volta che il messaggio è esaurito, poiché normalmente $è consentito abbinare dove ¶$corrisponderebbe.

M!s`.*¶$

Elimina tutto se il messaggio non è stato completamente codificato.

Rimuovere le nuove righe dall'output.


Penso che non passi dal penultimo test case (che, per essere onesti, non avevo nel post iniziale).
jkpate,

@jkpate Grazie per averlo sottolineato; Ho dovuto riscrivere leggermente il mio approccio.
Neil,

0

Pulito , 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]

Provalo online!

Prende prima il corriere, quindi il messaggio.

Errori con Run time error, rule '$;2' in module 'main' does not matchse il messaggio non si adatta.


0

Rubino , 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:''}

Provalo online!

Funzione ricorsiva, accetta input come matrice di caratteri.

Per una volta speravo di usare il squeezemetodo integrato di Ruby che contrae esecuzioni consecutive dello stesso personaggio in una singola istanza. Ma sfortunatamente, no - gli ultimi due casi di test hanno rovinato tutto così tanto, che ho dovuto ricorrere a un approccio completamente diverso, e questo si è rivelato fondamentalmente un porto della risposta di Arnauld .


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)

Lo script restituisce empty stringse il corriere non contiene i caratteri del messaggio nel giusto ordine.

Script di test meno golfato:

$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"
}

Produzione:

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

0

C (gcc) , 69 + 12 = 81 byte

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

Compila con (12 byte)

-Dp=putchar(

Provalo 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
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.