Esteganografía de doble letra

19

La esteganografía oculta un mensaje dado dentro de un operador dado, produciendo un paquete que no parece sospechoso. Para este desafío, escribirá un programa que toma un mensaje ASCII y un operador ASCII como entrada, y devolverá o imprimirá un paquete que sea idéntico al operador, excepto que los caracteres correspondientes al mensaje se duplican, en el mismo orden en que aparecen el mensaje.

Reglas:

  1. Si el operador ya contiene secuencias del mismo carácter más de una vez, y no se utilizan para codificar un carácter del mensaje, el programa las reducirá a un solo carácter.
  2. Si el operador no contiene los caracteres del mensaje en el orden correcto, el programa puede no devolver nada, el propio operador o un error.
  3. Puede suponer que el mensaje y el operador son cadenas ASCII no vacías.
  4. La capitalización importa: A no es equivalente a a.
  5. Cuando más de un paquete es válido, su programa puede generar alguno o todos ellos.
  6. El espacio es un personaje como cualquier otro personaje.

Casos de prueba:

Paquete de mensajería
"hola" "¿ha llegado?" "¿Ha llegado?" O "¿ha surgido?"
"señor" "¿ha llegado?" "¿Ha llegado?"
"foo" "¿ha llegado?" "" O "ha llegado?" O un error.
"Coche" "Los gatos son geniales". "CCaats arre col".
"coche" "Los gatos son geniales". "" O "Los gatos son geniales". O un error.
"Sofá" "Sofá" "CCoouucchh"
"oo" "oooooooooo" "oooo"
"o o" "oooo oooa" "oo ooa"

Este es el código de golf, por lo que gana menos bytes.

jkpate
fuente
55
No es sospechoso en absoluto ...: P
Quintec
¿Es "oooo oa"(con 2 espacios) una salida válida para el último caso de prueba?
Arnauld
3
No es una salida válida porque el orden de los caracteres duplicados en el paquete debe coincidir con el orden de los caracteres en el mensaje. En el mensaje, tenemos una 'o', luego una '', luego una 'o', pero su paquete tiene el espacio después de las o's
jkpate
Ah sí, eso tiene sentido.
Arnauld
1
No. Mi razonamiento detrás de esta regla es que la salida del programa en el caso de que no haya solución no debe ser inequívoca de que no hay solución posible. Las tres salidas permitidas son inequívocas, pero se requeriría una verificación más extensa para el caso deduplicado.
jkpate

Respuestas:

5

Jalea , 28 bytes

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

Un programa completo que toma carriery messagecomo argumentos de línea de comando que imprime el resultado
(para un no empacable messageimprime sin cambios carrier).

Pruébalo en línea! O vea el conjunto de pruebas .

¿Cómo?

ẹⱮŒ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
fuente
3

JavaScript (ES6), 71 bytes

Toma entrada como (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

Pruébalo en línea!


Versión alternativa, 66 bytes.

Si podemos tomar el mensaje como una matriz de caracteres:

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

Pruébalo en línea!


Editar : Gracias a @tsh por notar que olvidé eliminar algún código al cambiar de versiones no recursivas a versiones recursivas.

Arnauld
fuente
Se puede eliminar p=ya que p se pasa por un parámetro.
tsh
@tsh Uy. Es un código residual de las versiones anteriores no recursivas que olvidé eliminar. ¡Gracias!
Arnauld
2

Haskell, 124 121 107 101 97 95 90 bytes

(#).(++"ü")
"ü"#[]=[]
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

Provoca la excepción "Patrones no exhaustivos" si el operador no contiene el mensaje.

Pruébalo en línea!

Editar: -5 bytes gracias a @Laikoni.

nimi
fuente
Creo que cambiar los casos le permite abandonar m==c: ¡ Pruébelo en línea!
Laikoni
1

Retina 0.8.2 , 67 bytes

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

Pruébalo en línea! Toma el operador en la primera línea y el mensaje en la segunda línea. Explicación:

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

Procese ejecuciones de 1 o más caracteres idénticos del transportista. Si también hay una ejecución de 1 o más de los mismos caracteres en el mensaje, agregue la más corta de las dos ejecuciones a la salida por duplicado; de lo contrario, agregue un solo carácter de la portadora a la salida. Cada serie de caracteres de salida se termina con una nueva línea para distinguirla de la entrada. Al (?!¶)final, evita que la expresión regular piense que el transportista es el mensaje una vez que el mensaje se agota, ya que normalmente $se permite que coincida con el ¶$que correspondería.

M!s`.*¶$

Elimine todo si el mensaje no se codificó por completo.

Elimine las nuevas líneas de la salida.

Neil
fuente
Creo que no pasa el penúltimo caso de prueba (que, para ser justos, no tuve en la publicación inicial).
jkpate
@jkpate Gracias por señalar eso; He tenido que reescribir mi enfoque ligeramente.
Neil
0

Limpio , 118 bytes

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]

Pruébalo en línea!

Primero toma el transportista, luego el mensaje.

Errores con Run time error, rule '$;2' in module 'main' does not matchsi el mensaje no cabe.

Οurous
fuente
0

Ruby , 73 bytes

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

Pruébalo en línea!

Función recursiva, toma entradas como matriz de caracteres.

Por una vez, esperaba utilizar el squeezemétodo incorporado de Ruby que contrae ejecuciones consecutivas del mismo personaje en una sola instancia. Pero desafortunadamente, no, los dos últimos casos de prueba arruinaron todo tan mal que tuve que recurrir a un enfoque completamente diferente, y esto resultó ser básicamente un puerto de la respuesta de Arnauld .

Kirill L.
fuente
0

Powershell, 134 bytes

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)

El script devuelve el empty stringsi el operador no contiene los caracteres del mensaje en el orden correcto.

Menos guión de prueba de 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"
}

Salida:

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
fuente
0

C (gcc) , 69 + 12 = 81 bytes

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

Compilar con (12 bytes)

-Dp=putchar(

Pruébalo en línea!

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
fuente