Kotak Steganografis

14

Kotak Steganografis

Tugas Anda adalah mengambil string, dan menghasilkan NxNgambar yang mewakili string ini. Anda juga harus menulis algoritma yang mengambil gambar dan mengubahnya kembali menjadi string juga. Skor akan mencakup jumlah byte dari kedua algoritma:

Algoritma "Enkripsi" + Algoritma "Dekripsi" .

Anda harus memposting masing-masing secara terpisah, dengan byte-hitungan untuk kedua algoritma enkripsi dan dekripsi ditampilkan secara individual.


Contoh Algoritma

Misalnya, inilah "Programming Puzzles and Code Golf" menggunakan algoritme steganografi sederhana berbasis ASCII di saluran Biru:

#2e7250,#6ea972,#04eb6f,#0fc767,#74ab72,#ee6161
#b73b6d,#1aae6d,#f37169,#bda56e,#1fe367,#e99620
#706450,#0d3575,#146b7a,#4ea47a,#2a856c,#95d065
#3f2d73,#cef720,#bab661,#d1b86e,#f22564,#12b820
#0f3d43,#c86e6f,#1ee864,#a66565,#247c20,#c3bb47
#0e296f,#89d46c,#585b66,#c08f20,#455c20,#136f20

Gambar Aktual ( Gambar yang dihasilkan oleh algoritma.)

Gambar meledak-ledak.

Anda dapat melihat saluran biru cukup memegang nilai ascii untuk gambar ini:

50 =  80(P) 72 = 114(r) 6f = 111(o) 67 = 103(g) 72 = 114(r) 61 =  97(a) 
6d = 109(m) 6d = 109(m) 69 = 105(i) 6e = 110(n) 67 = 103(g) 20 =  32( ) 
50 =  80(P) 75 = 117(u) 7a = 122(z) 7a = 122(z) 6c = 108(l) 65 = 101(e) 
73 = 115(s) 20 =  32( ) 61 =  97(a) 6e = 110(n) 64 = 100(d) 20 =  32( ) 
43 =  67(C) 6f = 111(o) 64 = 100(d) 65 = 101(e) 20 =  32( ) 47 =  71(G) 
6f = 111(o) 6c = 108(l) 66 = 102(f) 20 =  32( ) 20 =  32( ) 20 =  32( )

Sementara saluran lainnya menyimpan nilai yang dihasilkan secara acak untuk "meningkatkan" variasi warna dalam gambar. Saat menarik pesan keluar dari gambar, kita bisa mengabaikan nilai saluran lainnya, dan menarik bit heks di saluran biru, merekonstruksi string:

"Programming Puzzles and Code Golf"

Perhatikan bahwa spasi yang digunakan untuk menempelkan string dalam kuadrat tidak termasuk dalam output dekripsi akhir. Meskipun Anda harus membuat string pada gambar, Anda dapat mengasumsikan bahwa string input tidak akan berakhir dengan spasi.


Aturan

  • Anda harus menyandikan 1 karakter per piksel, saluran yang dipilih untuk menyandikan char adalah sewenang-wenang.
  • Saluran dari warna RGB lainnya harus diacak, selain dari yang Anda pilih untuk menyandikan string; ini berarti saluran akhir tanpa kode Anda harus antara 0x0000-0xFFFF(dipilih secara acak).
  • Mengekspresikan hasil akhir sebagai array 2D nilai warna RGB baik-baik saja 0x000000-0xFFFFFF, tidak perlu menggunakan pembuatan gambar kecuali jika Anda ingin bersenang-senang dengannya atau jika kurang byte. Jika Anda memilih untuk menampilkan sebagai string hex, awali string hex dengan #EG #FFFFFFatau #05AB1E. Anda dapat memisahkan dengan tab, koma, atau apa pun yang akan masuk akal secara horizontal, tetapi harus mempertahankan pola kuadrat; dengan kata lain, Anda harus menggunakan pemisahan baris baru yang sesuai.
  • Outputnya harus dalam kotak, dan string harus diisi dengan spasi di ujungnya untuk mengakomodasi ini. Ini artinya N≈SQRT(Input#Length()). Jika panjang input bukan kotak yang sempurna, Anda harus membulatkan Ndan menempelkan spasi.
  • Seperti yang dinyatakan sebelumnya, jika Anda melapisi dengan spasi dalam gambar, Anda tidak harus memasukkan karakter empuk dalam output "dekripsi" akhir.
  • Anda dapat mengasumsikan bahwa:
    • String input tidak akan berakhir dengan spasi.
    • String input hanya akan menggunakan karakter ASCII yang dapat dicetak.
  • Ini adalah , kemenangan jumlah byte terendah.
Guci Gurita Ajaib
sumber
Hanya untuk memperjelas, solusi harus mengkodekan / mendekode persis satu karakter per piksel?
ETHproduk
@ETHproduksi yang terdengar seperti tantangan tindak lanjut yang bagus, tetapi untuk tujuan kompetisi ini, Anda memilih saluran penyandian dan menyandikan 1 karakter per piksel.
Magic Gurita Guci
Saya mungkin tidak akan menggunakan ini, tetapi: apakah boleh "overpad" gambar dengan lebih banyak ruang daripada yang diperlukan? Dan apakah boleh mengasumsikan bahwa gambar akan memiliki jumlah overpadding yang sama dengan yang dihasilkan oleh pembuat enkode?
@ ais523 Saya tidak bisa melihat bagaimana jenis pendekatan ini akan melakukan apa pun kecuali memerlukan lebih banyak byte untuk diimplementasikan. Saya akan pergi dengan tidak, karena tantangannya terlalu tua untuk membuat perubahan besar seperti itu.
Magic Octopus Mm
1
Benar, saya tidak yakin apakah itu diizinkan dalam pertanyaan awal, daripada merekomendasikan perubahan. (Saya sedang berpikir tentang mengemas input ke dalam sebuah persegi panjang, yang memiliki perhitungan koordinat byte-lebih pendek yang lebih mudah dan lebih mudah daripada mengemasnya menjadi sebuah persegi, kemudian melapisi persegi tersebut ke sebuah persegi yang lebih besar.)

Jawaban:

2

05AB1E , 34 + 12 = 46 byte

Menggunakan saluran merah.
05AB1E menggunakan pengkodean CP-1252 .

Menyandi:

DgDtî©n-Äð×JvyÇh`4F15Ý.Rh«}})'#ì®ä

D                                   # duplicate input
 gDtî©n-Ä                           # abs(len(input)-round_up(sqrt(len(input)))^2)
         ð×J                        # join that many spaces to end of input
            v                       # for each char in string
             yÇ                     # get ascii value
               h`                   # convert to base-16 number
                 4F                 # 4 times do:
                   15Ý.Rh           # push random base-16 number
                         «          # concatenate
                          }}        # end inner and outer loop
                            )       # wrap in list
                             '#ì    # prepend a "#" to each element in list
                                ®ä  # split in pieces round_up(sqrt(len(input))) long

Cobalah online!

Membaca sandi:

˜vy3£¦HçJ}ðÜ

˜               # deep flatten input to a list
 v              # for each color in the list
  y3£           # take the first 3 chars
     ¦          # remove the hash sign
      H         # convert from base-16 to base-10
       ç        # get the ascii char with that value
        J       # join to string
         }      # end loop
          ðÜ    # remove trailing spaces

Cobalah online!

Metode padding alternatif dengan jumlah byte yang sama

Dgð×J¹gtî©n£
Emigna
sumber
Saya pikir Anda harus secara khusus bergabung di baris baru, sesuai pertanyaan? (Jawaban Anda kemungkinan akan mengalahkan jawaban saya walaupun itu disesuaikan untuk melakukan itu, karena saya hanya menghabiskan lima byte berurusan dengan bagian dari pertanyaan itu, dan Anda unggul lebih dari itu.)
@ ais523: Aturan menyatakan bahwa array 2D baik-baik saja. Apa aku salah paham tentang itu?
Emigna
"Anda dapat berpisah dengan tab, koma, atau apa pun yang akan masuk akal secara horizontal, tetapi harus mempertahankan pola kuadrat; dengan kata lain, Anda harus menggunakan pemisahan baris baru yang sesuai." sangat menyiratkan bahwa itu harus berupa string, karena array 2D tidak secara inheren mengandung baris baru. Dengan kata lain, saya menafsirkan "array" sebagai menggambarkan bentuk output, bukan tipe data output.
@ ais523: Saya sudah meminta OP untuk klarifikasi. Seperti yang Anda katakan, ini bukan perubahan besar untuk diterapkan, tetapi mungkin Anda dapat menyimpan beberapa byte juga jika format tidak diperlukan.
Emigna
@ ais523 bagaimanapun juga dapat diterima.
Magic Gurita Guci
4

C, 201 (Encoding) + 175 (Decoding) = 376 byte

Untuk Menyandikan:

E(char*J){size_t L=ceil(sqrt(strlen(J)));int U;srand(time(NULL));for(int i=0;i<L;i++){for(int f=0;f<L;f++){printf("#%02X%02X%02X ",rand()%256,(U<strlen(J))?(int)J[U]:32,rand()%256);U+=1;}printf("\n");}}

Mengkodekan setiap karakter string input dalam saluran hijau spektrum RGB sambil mengatur dua saluran lainnya sebagai nilai hex acak. Mengambil input melalui STDIN sebagai string dan output ke STDOUT string multiline kode warna hex dalam bentuk kotak. Dengan asumsi Anda telah menginstal Python 3 dan ImageMagick, dan file di atas dikompilasi ke dalam file yang bernama a.outdalam direktori kerja saat ini (CWD), Anda dapat langsung mendapatkan gambar yang dihasilkan, dinamai Output.png, ke CWD dari output tekstual menggunakan perintah berikut:

./a.out "<Multiline Input>"|python3 -c "import sys,subprocess;Input=sys.stdin.read();print('# ImageMagick pixel enumeration: {0},{0},255,rgb\n'.format(len(Input.split('\n')[1].split()))+'\n'.join(['%d,%d:(%d,%d,%d)'%(g,i,int(j[1:][:2],16),int(j[1:][2:4],16),int(j[1:][4:6],16))for g,h in enumerate(Input.split('\n'))for i,j in enumerate(h.split())]))"|convert - -scale 1000% Output.png

Berikut adalah contoh gambar output yang dibuat oleh commamd di atas menggunakan Programming Puzzles and Code Golfsebagai string input:

Output Sampel

Untuk Mendekodekan:

D(int c,char**U){char T[c];for(int Y=1;Y<c;Y++){char G[2]={U[Y][3],U[Y][4]};T[Y-1]=(char)strtol(G,NULL,16);}int C=c-1;T[C]='\0';while(T[C]==' '){T[C]='\0';C-=1;}printf("%s\n",T);}

Membawa input melalui STDIN urutan string kode warna heksa yang dipisahkan ruang dengan masing-masing tertutup dalam tanda kutip ganda ( ") ( char** argvdalam main) dan juga, ketika dipanggil main, int argcuntuk input integer. Output ke STDOUT string tunggal / multi-line yang mewakili pesan yang diterjemahkan.

Saya akan mencoba bermain golf ini dari waktu ke waktu kapan pun dan di mana pun saya bisa.


Juga, jika Anda menyamakan kedua metode ke dalam file yang sama, Anda dapat menggunakan mainmetode berikut untuk menyatukan semuanya dengan setiap fungsi mendapatkan input yang benar:

int main(int argc,char**argv){if(strcmp(argv[1],"E")==0){Encode(argv[2]);}else{Decode(argc,argv);}}

dan menggunakan ini, untuk pengkodean Anda harus memberikan Esebagai argumen pertama untuk memanggil metode pengkodean diikuti oleh argumen string tunggal, sedangkan untuk decoding, semua yang perlu Anda berikan adalah urutan string kode warna hex yang dipisahkan ruang dengan masing-masing tertutup dalam tanda kutip ganda ( ").


Akhirnya, jika Anda ingin, Anda bisa mendapatkan sepenuhnya siap, versi siap digunakan di sini , meskipun tidak golfed, tetapi juga tidak output setiap peringatan atau kesalahan pada kompilasi.

R. Kap
sumber
3

Python 2, 164 160 + 94 93 = 253 byte

Disimpan 1 + 1 byte berkat Wheat Wizard.

-5 byte berkat Kade

Gambar EncoderEncoder: string harus dilampirkan dalam tanda kutip, misalnya "CodeGolf", keluaran adalah gambar ascii PPM.

from random import*
s=input()
n=int((len(s)-1)**0.5)+1
s=s.ljust(n*n)
r=randint
print"P3 %d %d 255 "%(n,n)+''.join("%d "*3%(r(0,255),r(0,255),ord(c))for c in s)

Gambar DekoderDecoder: Mengambil input nama file sebagai argumen baris perintah

from sys import*
print''.join(chr(int(c))for c in open(argv[1]).read().split()[6::3]).strip()

Pemakaian:

 python golf_stegansquare_enc.py > stega.ppm

 python golf_stegansquare_dec.py stega.ppm

Contoh:

Teka-teki Pemrograman dan Golf KodeTeka-teki Pemrograman dan Golf Kode

Lorem IpsumAnda juga dapat memilih dari semua yang Anda inginkan, dan kemudian memilih yang lain, sementara tidak tersedia untuk sementara waktu tersedia di sini dan kemudian dengan mudah, dengan mudah dan mudah. Pada hari-hari terakhir dan kemudian hanya bersama-sama dolores dan kembali. Tidak ada foto yang tersedia, tidak ada laut takimata sanctus est Lorem ipsum dolor sit amet. Anda juga dapat memilih dari semua yang Anda inginkan, dan kemudian memilih yang lain, sementara tidak tersedia untuk sementara waktu tersedia di sini dan kemudian dengan mudah, dengan mudah dan mudah. Pada hari-hari terakhir dan kemudian hanya bersama-sama dolores dan kembali. Tidak ada foto yang tersedia, tidak ada laut takimata sanctus est Lorem ipsum dolor sit amet.

Karl Napf
sumber
Anda dapat menghapus ruang antara paren dekat dan kemudianfor
Post Rock Garf Hunter
@ ETProduksi: sqrt (25-1) = sqrt (24) <5 dan> 4. intdari ini adalah 4 yang kemudian +1diedit, jadi 5
Karl Napf
Oh, salahku, aku tidak melihatnya -1.
ETHproduk
1
Anda dapat menghapus ruang di antara printdan 'di decoder. Saya juga cukup yakin Anda bisa melakukan int((len(s)+1)**.5)untuk menghemat beberapa byte.
Kade
1
Saya sedang mengubah kalimat terakhir dari komentar saya sebelumnya, namun Anda dapat mempersingkat pencetakan dengan mengubah ' '.join("%d %d %d"ke ''.join(3*"%d "karena saya cukup yakin ruang tambahan tidak masalah.
Kade
2

Scala, 97 + 68 = 165 byte

Enkripsi (97 byte):

s=>s.map(_+((math.random*65535).toInt<<8)).iterator.grouped(math.sqrt(s.size)toInt)withPadding 32

Mengambil String dan mengembalikan Iterator dari Sequences of Integers.

Dekripsi (68 byte):

a=>" +$".r.replaceAllIn(a.flatten.map(h=>(h&0xFF)toChar)mkString,"")

Mengambil Iterator dari Sequences of Integers dan mengembalikan sebuah string.

Penjelasan:

s=>                         //define an anonymous function
  s.map(                      //map each char of the string
    _+(                         //to the ascii value plus
      (math.random*65535).toInt)  //a random integer between 0 and 65535
      <<8                         //shifted 8 bits to the left
    )
  )
  .iterator                     //create an iterator
  .grouped(                     //group them in groups of size...
    math.sqrt(s.size)toInt        //sqrt of the size of the input, rounded up
  )withPadding 32               //pad with spaces to make a square

.

a=>
  " +$"              //take this string
  .r                 //parse it as a regex
  .replaceAllIn(     //replace every occurence of the regex in...
    a.flatten          //a flattened
    .map(h=>           //each element mapped
      (h&0xFF)toChar)    //to the character of the lower 8 bits
    mkString,          //joined to a string
    ""               //with an empty string
  )
corvus_192
sumber
2

Perl, (103 + 1) + (36 + 2) = 142 byte

Encoder teks ke gambar (dijalankan dengan -ppenalti 1 byte; -p0(untuk byte tambahan penalti) diperlukan jika Anda ingin menangani baris baru dalam string input):

$_.=$"while($a=(length)**.5)=~/\./;$_=unpack"H*";s/../sprintf"#%04x$&,",rand+4**8/eg;s/(.*?\K,){$a}/
/g

Decoder gambar ke teks (dijalankan dengan -p0penalti 2 byte):

$\.=chr hex for/..\W/g;$\=~s/ *$//}{

Ini menggunakan #abcdefformat gambar berbasis teks, dan mengkodekan dalam saluran biru. Berikut adalah contoh dari kemungkinan output yang diberikan Programming Puzzles and Code Golfsebagai input:

# b4d250, # bccb72, # 43f06f, # 4d6767, # 74ba72, # 269461
# e4f26d, # f63d6d, # 701c69, # bbf56e, # 6ef967, # d78d20
# 4e0d50, # 9b2775, # afd37a, # 12a47a, # 63e46c, # 0e9565
# 4cad73, # e43420, # 6da761, # 5a306e, # 8fba64, # 58f720
# d52443, # b4446f, # fbaf64, # 4a4365, # 1a5020, # f3ea47
# 354c6f, # 52cb6c, # 11a766, # 4c380a, # 553820, # b31120

Penjelasan pembuat enkode:

$_.=$"             # append a space ($") to the input ($_)
  while            # as long as the following condition holds:
(($a=length)**.5)  # the square root of the input length (save this in $a)
=~/\./;            # has no decimal points in its string represenation
$_=unpack"H*";     # convert the input from base-256 to hexadecimal
s/../              # replace two characters of the input
  sprintf          # with a string formed from the template
  "#%04x$&,",      # four hex digits, the two matched characters, and a comma
  rand+4**8        # those hex digits are a random number from 0 to 4**8 (= 65536)
/eg;               # and do this for every non-overlapping match
s/(.*?             # find the minimum number of characters needed to match
   \K,)            # replacing the part of the match after the last matched comma
  {$a}/            # a string containing $a commas
/gx                # with a newline, for every non-overlapping match

Saya sangat senang penggunaan ini \Kberhasil; itu menentukan di mana untuk mengganti, dan menempatkannya di dalam sebuah loop, tampaknya bahwa terjadinya pada iterasi loop terakhir adalah yang terpenting. Jadi s/(.*?\K,){$a}/\n/gakan cocok dengan string minimum panjang dari bentuk apa pun koma apa pun koma ... apa pun koma, yang memiliki $akoma, tetapi bagian yang diganti sebenarnya dari pertandingan hanya akan menjadi koma terakhir. Ini memiliki efek mengganti setiap$a koma dengan baris baru, memberi kita bentuk persegi untuk gambar.

Keuntungan besar Perl untuk tantangan ini (selain konverter karakter string-ke-heksadesimal, yang sangat nyaman) adalah bahwa ia memiliki dekoder yang sangat pendek (begitu singkat, pada kenyataannya, bahwa meskipun Perl memiliki builtin untuk mengubah heksadesimal menjadi string, itu lebih pendek untuk tidak menggunakannya). Begini cara kerjanya:

$\.=chr      # append to $\ the character code
  hex        # of the hexadecimal-string-to-number-translation
for/..\W/g;  # of each two characters that appear before a
             # non-alphanumeric character (not counting overlapping matches)
$\=~s/ *$//  # delete all spaces at the end of $\
}{           # in this context, this means "implicitly print $\,
             # prevent any other implicit printing"

Satu-satunya contoh dari dua karakter tepat sebelum karakter non-alfanumerik adalah saluran biru (yang ingin kami ekstrak), yang muncul tepat sebelum koma dan baris baru; dan dua karakter yang muncul sebelum satu sama #lain daripada yang pertama. Kami tidak ingin kategori pertandingan yang terakhir, tetapi mereka pasti akan tumpang tindih dengan kategori sebelumnya, dan dengan demikian akan dikeluarkan oleh cek pertandingan yang tumpang tindih.


sumber
1

MySQL, 438 + 237 = 675 byte

Ada garis baru di akhir output, tetapi tidak muncul setelah didekripsi. Fungsi hex (integer overload) akan memangkas memimpin 0's, jadi saya harus memasangnya dengan string 0. Saya bisa menyimpan beberapa byte jika saya bisa mendeklarasikan kedua fungsi di antara pembatas.

Enkripsi

delimiter //create function a(i text)returns text begin declare r int;declare q,p text;while mod(length(i),sqrt(length(i)))<>0 do set i:=concat(i,' ');end while;set r:=1;set q:="";while r<=length(i) do set p:=",";if mod(r,sqrt(length(i)))=0 then set p:="\r\n";end if;set q:=concat(q,'#',right(concat(0,hex(floor(rand()*256))),2),right(concat(0,hex(floor(rand()*256))),2),hex(mid(i,r,1)),p);set r:=r+1;end while;return q;end//
delimiter ;

Dekripsi

delimiter //create function b(i text)returns text begin declare x int;declare y text;set x:=0;set y:="";while instr(i,'#')>0 do set i:=substr(i,instr(i,'#')+5);set y:=concat(y,unhex(left(i,2)));end while;return trim(y);end//
delimiter ;

Pemakaian:

select a('test')
select b('#7D1874,#FFB465')
select b(a('test'))
Wahooka
sumber
1

C #, 312 + 142 = 454 byte

Pengkodean:

using System;I=>{var r=new Random();int i=I.Length;int N=(int)Math.Floor(Math.Sqrt(i))+1,S=N*N;while(i++<S){I+=' ';}var R="";for(i=0;i<S;){R+=i%N<1&i>0?"\n":i<1?"":" ";R+="#"+r.Next(256).ToString("X").PadLeft(2,'0')+r.Next(256).ToString("X").PadLeft(2,'0')+((int)I[i++]).ToString("X").PadLeft(2,'0');}return R;};

Decoding:

using System;I=>{var s=I.Replace('\n',' ').Split(' ');var R="";foreach(var t in s)R+=(char)System.Convert.ToInt32(t[5]+""+t[6],16);return R.TrimEnd(' ');};

Program lengkap:

using System;
class Steganographic
{
    static void Main()
    {
        Func<string, string> E = null;
        Func<string, string> D = null;

        E=I=>
        {
            var r=new Random();
            int i=I.Length;
            int N=(int)Math.Floor(Math.Sqrt(i))+1,S=N*N;
            while(i++<S){I+=' ';}
            var R="";
            for(i=0;i<S;)
            {
                R+=i%N<1&i>0?"\n":i<1?"":" ";
                R+="#"+r.Next(256).ToString("X").PadLeft(2,'0')+r.Next(256).ToString("X").PadLeft(2,'0')+((int)I[i++]).ToString("X").PadLeft(2,'0');
            }
            return R;
        };

        D=I=>
        {
            var s=I.Replace('\n',' ').Split(' ');
            var R="";
            foreach(var t in s)
                R+=(char)Convert.ToInt32(t[5]+""+t[6],16);
            return R.TrimEnd(' ');
        };

        string encoded = E("Programming Puzzles and Code Golf");
        Console.WriteLine(encoded);
        Console.WriteLine(D(encoded));

        encoded = E("Hello, World!");
        Console.WriteLine(encoded);
        Console.WriteLine(D(encoded));

        Console.Read(); // For Visual Studio
    }
}
Yodle
sumber
1

Mathematica, 111 + 65 = 176 byte

Encoder

Join[255~RandomInteger~{n=⌈Sqrt@Length@#⌉,n,2},ArrayReshape[#,{n,n,1},32],3]~Image~"Byte"&@*ToCharacterCode

Dekoder

StringTrim[""<>FromCharacterCode@ImageData[#,"Byte"][[;;,;;,3]]]&
JungHwan Min
sumber
1

Memproses, 220 209 194 + 171 167 151 = 391 380 376 361 345 byte

Memperbarui:

Dihapus tidak berguna noStroke() dan membuat keduanya for-loop one-statementer.

Dihapus tidak berguna image(p,0,0); , berikan nama file decryptor sebagai parameter

Algoritma Enkripsi

void g(String h){int s=ceil(sqrt(h.length()));for(int y=0,x;y<s;y++)for(x=0;x<s;rect(x,y,1,1),x++)stroke(h.length()>y*s+x?h.charAt(y*s+x):32,random(255),random(255));get(0,0,s,s).save("t.png");}

Memanggil fungsi: g("Programming Puzzles and Code Golf");

Ini adalah fungsi yang mengambil String, dan menciptakan output, sebelum menyimpannya sebagai t.png. Ini menggunakanred nilai untuk menyimpan teks tersembunyi.

Algoritma Dekripsi

void u(String f){PImage p=loadImage(f);f="";for(int j=0,i;j<p.height;j++)for(i=0;i<p.width;i++)f+=(char)red(p.get(i,j));print(f.replaceAll(" +$",""));}

Fungsi panggilan dengan: u(file_name);

Ini juga merupakan fungsi yang mencari gambar yang ditentukan oleh parameter, dan kemudian menampilkan string yang tersembunyi (karena lebih pendek daripada mengembalikan string).

Kode diperluas

(Algoritma Enkripsi)

void g(String h) {
  int s=ceil(sqrt(h.length()));
  for(int y=0,x;y<s;y++)
    for(x=0;x<s;rect(x,y,1,1),x++)
      stroke(h.length()>y*s+x?h.charAt(y*s+x):32,random(255),random(255));
  get(0,0,s,s).save("t.png");
}

String dilewatkan ketika fungsi dipanggil. Baris pertama dari fungsi menghitung panjang sisi persegi dengan mengambil ceildari akar kuadratnya. Kemudian kita memasukkan for-loop, di mana kita mengatur stroke(warna tepi) untuk memiliki nilai ASCII karakter sebagai merah, dan nilai acak untuk biru dan hijau. Setelah kita melakukan ini, kita membuat rect(persegi panjang) dengan width = 1dan height = 1, yaitu pixel (untuk beberapa alasan aneh, saya tidak dapat menggunakan pointdengan benar). Di baris terakhir, gambar yang dihasilkan kemudian disimpan sebagai t.png.

(Algoritma Dekripsi)

void u(String f) {
  PImage p=loadImage(f);
  f="";
  for(int j=0,i;j<p.height;j++)
    for(i=0;i<p.width;i++)
      f+=(char)red(p.get(i,j));
  print(f.replaceAll(" +$",""));
}

Fungsi ini memiliki nama file sebagai parameter (sebagai string). Kemudian gambar dalam file tersebut disimpan dalam variabel untuk digunakan nanti. Setelah kita selesai dengan itu, kita mengatur string ""daripada membuat string baru hanya untuk menahan string yang tersembunyi. Kemudian kita beralih melalui gambar melalui dua bersarang untuk-loop, dan kami menambahkan ke string nilai karakter dari nilai merah piksel. Akhirnya, kami mencetak string yang dihasilkan setelah menghapus spasi di depan (menggunakan regex). Alasan kami mencetak teks tersembunyi daripada mengembalikannya adalah karena cara ini lebih pendek dan kami menghemat byte.


Teks mentah tantangan terenkripsi:

masukkan deskripsi gambar di sini

Kritixi Lithos
sumber
1

Jelly, 40 + 20 = 60 byte dalam codepage Jelly

Encoder (teks → gambar):

”#;;ØHX¤¥4¡
»⁶x⁹²¤¤Ob⁴‘ịØHÇ€sj€”,Y
L½Ċç@

Cobalah online!

Dekoder (gambar → teks):

ḣ2ØHiЀ’ḅ⁴Ọ
ṣ”#Ç€œr⁶

Cobalah online!

Contoh keluaran yang bisa dihasilkan oleh program (ini menyimpan informasi dalam saluran merah):

#504219,#720200,#6F38F1,#67055F,#7228C7,#61AC95
#6DD797,#6D20CB,#6962FA,#6E69B1,#67C41C,#209436
#50CB19,#75C9FC,#7A1B06,#7A695B,#6C5D5B,#6539A6
#735925,#20C80F,#612C38,#6EBF9E,#64C79E,#200915
#4337C5,#6F4704,#64FB5F,#65B2D1,#20E075,#47BC7C
#6F0C16,#6CD8EF,#66060B,#203C6C,#20D6E9,#20C0D7

Dalam tantangan yang lebih besar ini, keleness Jelly mulai berkurang sedikit, membutuhkan beberapa karakter "struktural" untuk menyelesaikan ambiguitas parsing, tapi tetap saja masih sangat singkat. Inilah cara kerja pembuat enkode:

Subroutine 1: convert digits to randomly padded hex string
”#;;ØHX¤¥4¡
”#;                     prepend #
    ØHX                 random hexadecimal digit
       ¤                parse ØH and X as a unit
   ;                    append
        ¥               parse ; and ØHX¤ as a unit
         4¡             repeat four times

Subroutine 2: convert string λ to square with size ρ
»⁶x⁹²¤¤Ob⁴‘ịØHÇ€sj€”,Y
 ⁶                      space
   ⁹²                   ρ squared
     ¤                  parse ⁹² as a unit
  x                     repeat string (i.e. ρ² spaces)
      ¤                 parse ⁶x⁹²¤ as a unit
»                       take maximum
Because space has the lowest value of any printable ASCII character,
this has the effect of padding λ to length ρ² with spaces.
       O                take codepoints of string
        b⁴              convert to base 16
           ịØH          use as indexes into a list of hexadecimal digits
          ‘             0-indexed (Jelly uses 1-indexing by default)
              ǀ        run subroutine 1 on each element
                s       split into groups of size ρ
                  €     inside each group
                 j ”,   join on commas
                     Y  join on newlines

Main program: basically just calculates ρ and lets subroutine 2 do the work
L½Ċç@
L                       length of input
 ½                      square rooted
  Ċ                     rounded up to the next highest integer
   ç@                   call subroutine 2 with the original input and the above

Dan inilah cara dekoder bekerja:

Subroutine: convert hexadecimal color string (without #) to character
ḣ2ØHiЀ’ḅ⁴Ọ
ḣ2                      take first two characters
  ØHi                   find indexes in a string of hexadecimal digits
     Ѐ                 for each of those characters
       ’                0-indexed (Jelly uses 1-indexing by default)
        ḅ⁴              convert from base 16
          Ọ             convert integer to character

Main program:
ṣ”#Ç€œr⁶
ṣ”#                     split on # signs
   ǀ                   run the subroutine for each element
     œr⁶                remove spaces from the right

sumber