Steganography nhân đôi


19

Steganography ẩn một thông điệp nhất định bên trong một hãng vận chuyển nhất định, tạo ra một gói không có vẻ đáng ngờ. Đối với thử thách này, bạn sẽ viết chương trình lấy thông điệp ASCII và nhà cung cấp ASCII làm đầu vào và trả lại hoặc in một gói giống hệt với nhà cung cấp ngoại trừ các ký tự tương ứng với thông báo được nhân đôi, theo cùng thứ tự xuất hiện trong thông điệp.

Quy tắc:

  1. Nếu nhà mạng đã chứa các chuỗi cùng một ký tự nhiều lần và chúng không được sử dụng để mã hóa một ký tự của tin nhắn, chương trình sẽ giảm chúng thành một ký tự.
  2. Nếu nhà cung cấp dịch vụ không chứa các ký tự thông báo theo đúng thứ tự, chương trình có thể không trả về gì, bản thân nhà mạng hoặc lỗi.
  3. Bạn có thể giả sử rằng thông điệp và nhà cung cấp là các chuỗi ASCII không trống.
  4. Vấn đề viết hoa: A không tương đương với a.
  5. Khi có nhiều hơn một gói hợp lệ, chương trình của bạn có thể xuất bất kỳ hoặc tất cả các gói đó.
  6. Không gian là một nhân vật như bất kỳ nhân vật khác.

Các trường hợp thử nghiệm:

Gói tin nhắn
"hi" "đã đến chưa?" "hah iit arived?" HAY "nó đã được kích hoạt?"
"thưa ngài" "đã đến chưa?" "rắc rối iit đã đến?"
"foo" "đã đến chưa?" "" HOẶC "đã đến chưa?" HOẶC một lỗi.
"Xe" "Mèo thật ngầu." "CCaats arre col."
"xe hơi" "Mèo thật ngầu." "" HOẶC "Mèo thật tuyệt." HOẶC một lỗi.
"Ghế" "Ghế" "CCoouucchh"
"oo" "oooooooooo" "oooo"
"o o" "oooo oooa" "oo ooa"

Đây là mã golf, vì vậy ít byte nhất sẽ thắng.


5
Không nghi ngờ gì cả ...: P
Quintec

"oooo oa"(với 2 khoảng trắng) là đầu ra hợp lệ cho trường hợp thử nghiệm cuối cùng?
Arnauld

3
Nó không phải là đầu ra hợp lệ vì thứ tự các ký tự nhân đôi trong gói phải khớp với thứ tự của các ký tự trong tin nhắn. Trong tin nhắn, chúng tôi có một 'o', sau đó là '', rồi 'o', nhưng gói của bạn có khoảng trống sau o's
jkpate

À đúng, điều đó có ý nghĩa.
Arnauld

1
Không. Lý do của tôi đằng sau quy tắc này là đầu ra của chương trình trong trường hợp không có giải pháp nào nên rõ ràng rằng không có giải pháp nào khả thi. Ba đầu ra được phép là không rõ ràng, nhưng sẽ cần phải kiểm tra rộng hơn cho trường hợp bị trùng lặp.
jkpate

Câu trả lời:


5

Thạch , 28 byte

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

Một chương trình đầy đủ lấy carriermessagelàm đối số dòng lệnh in kết quả
(Đối với messagebản in không đóng gói được in không thay đổi carrier).

Hãy thử trực tuyến! Hoặc xem bộ thử nghiệm .

Làm sao?

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

Đưa đầu vào là (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

Hãy thử trực tuyến!


Phiên bản thay thế, 66 byte

Nếu chúng ta có thể lấy thông điệp dưới dạng một mảng các ký tự:

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

Hãy thử trực tuyến!


Chỉnh sửa : Cảm ơn @tsh vì đã nhận thấy rằng tôi đã quên xóa một số mã khi chuyển từ phiên bản không đệ quy sang phiên bản đệ quy.


Bạn có thể loại bỏ p=vì p được truyền bởi một tham số.
tsh

@tsh Rất tiếc. Đó là một số mã còn lại từ các phiên bản trước, không đệ quy mà tôi quên xóa. Cảm ơn bạn!
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

Tăng ngoại lệ "Mẫu không toàn diện" nếu nhà mạng không chứa thông báo.

Hãy thử trực tuyến!

Chỉnh sửa: -5 byte nhờ @Laikoni.


Tôi nghĩ việc chuyển đổi các trường hợp cho phép bạn bỏ m==c: Hãy thử trực tuyến!
Laikoni

1

Võng mạc 0.8.2 , 67 byte

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

Hãy thử trực tuyến! Đưa người vận chuyển trên dòng đầu tiên và thông báo trên dòng thứ hai. Giải trình:

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

Quá trình chạy từ 1 hoặc nhiều ký tự giống hệt nhau của sóng mang. Nếu cũng có một hoặc nhiều ký tự giống nhau trong tin nhắn, sau đó nối ngắn hơn hai lần chạy vào đầu ra theo bản sao, nếu không thì thêm một ký tự của sóng mang vào đầu ra. Mỗi lần chạy các ký tự đầu ra được kết thúc bằng một dòng mới để phân biệt nó với đầu vào. Các (?!¶)đồng ngăn chặn cuối cùng regex từ suy nghĩ hãng phân phối này được thông báo khi tin nhắn được cạn kiệt, như bình thường $được phép để phù hợp với nơi ¶$sẽ phù hợp.

M!s`.*¶$

Xóa mọi thứ nếu tin nhắn không được mã hóa hoàn toàn.

Loại bỏ các dòng mới từ đầu ra.


Tôi nghĩ rằng nó không vượt qua trường hợp thử nghiệm thứ hai đến lần cuối (mà công bằng mà nói, tôi không có trong bài viết ban đầu).
jkpate

@jkpate Cảm ơn bạn đã chỉ ra điều đó; Tôi đã phải viết lại cách tiếp cận của tôi một chút.
Neil

0

Sạch , 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]

Hãy thử trực tuyến!

Đưa người vận chuyển trước, sau đó là tin nhắn.

Lỗi với Run time error, rule '$;2' in module 'main' does not matchnếu tin nhắn không phù hợp.


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

Hãy thử trực tuyến!

Hàm đệ quy, lấy đầu vào là mảng ký tự.

Lần đầu tiên tôi đã hy vọng sử dụng squeezephương thức tích hợp sẵn của Ruby để hợp đồng chạy liên tiếp cùng một ký tự với một thể hiện duy nhất. Nhưng thật không may, không - hai trường hợp thử nghiệm cuối cùng đã làm hỏng mọi thứ rất tệ, đến nỗi tôi phải dùng đến một cách tiếp cận hoàn toàn khác, và điều này hóa ra về cơ bản là một câu trả lời của 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)

Kịch bản trả về empty stringnếu nhà mạng không chứa các ký tự thông báo theo đúng thứ tự.

Kịch bản kiểm tra ít chơi gôn hơn:

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

Đầu ra:

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;}

Biên dịch với (12 byte)

-Dp=putchar(

Hãy thử trực tuyến!

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
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.