ステガノグラフィックスクエア


14

ステガノグラフィックスクエア

あなたの仕事は、文字列を取り込み、NxNこの文字列を表す画像を生成することです。また、画像を取り込んで、文字列に戻すアルゴリズムも記述する必要があります。スコアリングには、両方のアルゴリズムのバイトカウントが含まれます。

「暗号化」アルゴリズム+「復号化」アルゴリズム

暗号化アルゴリズムと復号化アルゴリズムの両方のバイト数を個別に表示して、それぞれを個別に投稿する必要があります。


アルゴリズム例

たとえば、ブルーチャネルで単純なASCIIベースのステガノグラフィックアルゴリズムを使用した「プログラミングパズルとコードゴルフ」は次のとおりです。

#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

実際の画像(アルゴリズムによって生成された画像。

画像の拡大。

青いチャネルがこの画像のascii値を保持していることがわかります。

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( )

残りのチャンネルはランダムに生成された値を保持して、画像のさまざまな色を「スパイスアップ」します。メッセージをイメージからプルアウトするとき、他のチャンネル値を単に無視し、青チャンネルの16進ビットをプルして、文字列を再構築できます。

"Programming Puzzles and Code Golf"

正方形の文字列の埋め込みに使用されたスペースは、最終的な復号化された出力に含まれていないことに注意してください。画像に文字列を埋め込む必要がありますが、入力文字列がスペースで終わらないと仮定することができます。


ルール

  • ピクセルごとに1文字をエンコードする必要があります。charをエンコードするために選択されたチャネルは任意です。
  • 他のRGBカラーのチャンネルは、文字列をエンコードするために選択するチャンネル以外のランダム化する必要があります。これは、最終的にエンコードされていないチャンネルが0x0000-0xFFFF(ランダムに選択された)間にある必要があることを意味します。
  • 最終結果をRGBカラー値の2D配列として表現するのは問題0x000000-0xFFFFFFありません。楽しみたい場合やバイト数が少ない場合を除き、イメージ作成を使用する必要はありません。16進文字列として出力する場合は、16進文字列の前に#EG #FFFFFFまたはを付け#05AB1Eます。タブ、コンマ、または水平方向に適切なもので区切ることができますが、正方形のパターンを維持する必要があります。つまり、適切な改行区切りを使用する必要があります。
  • 出力は正方形である必要があり、文字列はこれを収容するために最後にスペースを埋める必要があります。これはそれを意味しN≈SQRT(Input#Length())ます。入力長が完全な正方形でない場合は、切り上げてNスペースを埋める必要があります。
  • 前述のように、画像にスペースを埋める場合、最終的な「復号化された」出力に埋め込まれた文字を含めないでください。
  • あなたはそれを仮定することができます:
    • 入力文字列はスペースで終了しません。
    • 入力文字列は、印刷可能なASCII文字のみを使用します。
  • これは、最低バイト数が勝ちます。

明確にするために、ソリューションはピクセルごとに正確に 1文字をエンコード/デコードする必要がありますか?
ETHproductions

フォローアップの挑戦のように聞こえる@ETHproductionsですが、この競争の目的のために、エンコードチャンネルを選択し、ピクセルあたり1文字をエンコードします。
魔法のタコ

私はおそらくこれを使用するつもりはありませんが、必要以上のスペースで画像を「オーバーパッド」しても大丈夫ですか?そして、エンコーダーが生成するのと同じ量のオーバーパディングが画像にあると仮定しても大丈夫ですか?

@ ais523このタイプのアプローチがどのように機能するかはわかりませんが、実装するにはより多くのバイトが必要です。ただし、このような大きな変更を加えるには課題が古すぎるため、私は何もしません。
魔法のタコUr

1
そうです、変更を推奨するのではなく、元の質問でそれが許可されているかどうかはわかりませんでした。(入力を四角形にパックすることを考えていたので、四角形にパックするよりも簡単で、おそらくバイトが短い座標計算を行ってから、四角形を大きな四角形にパディングします。)

回答:


2

05AB1E、34 + 12 = 46バイト

赤チャネルを使用します。
05AB1EはCP-1252エンコードを使用します。

エンコード:

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

オンラインでお試しください!

デコード:

˜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

オンラインでお試しください!

等しいバイト数の代替パディング方法

Dgð×J¹gtî©n£

質問によると、特に改行に参加する必要があると思いますか?(質問のその部分を処理するのに5バイトしか費やさなかったので、あなたの答えはそれを行うように適合している場合でもおそらく私を打ち負かすでしょう、そしてあなたはそれ以上先です。)

@ ais523:ルールは、2D配列は大丈夫だと述べています。どういうわけか私はそれを誤解しましたか?
エミグナ16

「タブ、コンマ、または水平方向に適切なもので区切ることができますが、正方形のパターンを維持する必要があります。つまり、適切な改行区切りを使用する必要があります。」2D配列には本質的に改行が含まれないため、文字列にする必要があることを強く意味します。言い換えると、「配列」は、出力のデータ型ではなく、出力の形状を記述するものとして解釈しました。

@ ais523:OPに説明を求めました。あなたが言うように、実装することは大きな変更ではありませんが、フォーマットが必要ない場合は、おそらくいくつかのバイトを節約することもできます。
エミグナ16

どちらの方法でも@ ais523は受け入れられます。
魔法のタコUr

4

C、201(エンコード)+ 175(デコード)= 376バイト

エンコードするには:

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

RGBスペクトルの緑のチャネルの入力文字列の各文字をエンコードし、他の2つのチャネルをランダムな16進値として設定します。STDINを介して入力を文字列として受け取り、正方形の形状の16進カラーコードの複数行の文字列をSTDOUTに出力します。Python 3とImageMagickがインストールされており、上記のファイルがa.out現在の作業ディレクトリ(CWD)で名前が付けられたファイルにコンパイルされていると仮定するとOutput.png、次のコマンドを使用して、テキスト出力からCWDへの名前付きの結果イメージを直接取得できます:

./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

Programming Puzzles and Code Golf入力文字列として使用する上記のcomammdによって作成されたサンプル出力イメージは次のとおりです。

サンプル出力

デコードするには:

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

二重引用符(で囲まれた各一つとスペースで区切ら進カラーコード列の配列STDINを介して入力を受け取り"()char** argvmainで呼び出されたときに、また)とmainint argc整数入力のために。デコードされたメッセージを表す単一/複数行の文字列をSTDOUTに出力します。

私はいつでもどこでもできるように、これらをもっと時間をかけてゴルフしようとします。


また、同じファイルに両方のメソッドを同じ場合、次のmainメソッドを使用して、各関数が正しい入力を取得するようにすべてをまとめることができます。

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

これを使用して、エンコードの場合E、エンコードメソッドを呼び出す最初の引数として指定し、その後に単一の文字列引数を指定する必要があります。二重引用符(")。


最後に、必要に応じて、完全に準備されたすぐに使用できるバージョンをここで入手できますが、ゴルフではありませんが、コンパイル時に警告やエラー出力しません。


3

Python 2、164 160 + 94 93 = 253バイト

Wheat Wizardのおかげで1 + 1バイトを節約しました。

Kadeのおかげで-5バイト

エンコーダー画像エンコーダー:文字列は引用符で囲む必要があります。たとえば"CodeGolf"、出力はカラー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)

デコーダー画像デコーダー:コマンドライン引数として入力ファイル名を取得します

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

使用法:

 python golf_stegansquare_enc.py > stega.ppm

 python golf_stegansquare_dec.py stega.ppm

例:

プログラミングパズルとコードゴルフプログラミングパズルとコードゴルフ

ロレムイプサム座ってください、sad dipsing elitr、sed diam nonumy eirmod tempor invidunt ut Labore et dolore magna aliquyam erat、sed diam voluptua。vero eos et accusam et justo duo dolores et ea rebum。クリタ・カスド・グベルグレン、海のタキマタ・サンクトゥス、ロレム・イプサム・ドロルは座りませんでした。座ってください、sad dipsing elitr、sed diam nonumy eirmod tempor invidunt ut Labore et dolore magna aliquyam erat、sed diam voluptua。vero eos et accusam et justo duo dolores et ea rebum。クリタ・カスド・グベルグレン、海のタキマタ・サンクトゥス、ロレム・イプサム・ドロルは座りませんでした。


あなたは近い括弧の間にスペースを削除してすることができますfor
ポストロックGARFハンター

@ETHproductions:sqrt(25-1)= sqrt(24)<5および> 4. int+1
これから

ああ、私の悪い、私は見ませんでした-1
ETHproductions

1
あなたは、間にスペースを削除することができますprintし、'デコーダに。またint((len(s)+1)**.5)、いくつかのバイトを節約することができると確信しています。
ケード

1
前のコメントの最後の文を編集していますが、末尾のスペースは問題ないと確信している' '.join("%d %d %d"ため''.join(3*"%d "、に変更することで印刷を短縮できます。
ケード

2

Scala、97 + 68 = 165バイト

暗号化(97バイト):

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

文字列を取得し、整数シーケンスの反復子を再調整します。

復号化(68バイト):

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

整数のシーケンスのイテレータを取り、文字列を返します。

説明:

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
  )

2

Perl、(103 + 1)+(36 + 2)= 142バイト

テキスト-pツーイメージエンコーダー(1バイトのペナルティーで実行; -p0(追加のペナルティーのバイトで)入力文字列の改行を処理する場合に必要です):

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

画像からテキストデコーダー(-p02バイトのペナルティで実行):

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

これは、#abcdefテキストベースの画像形式を使用し、青チャンネルでエンコードします。Programming Puzzles and Code Golf入力として指定可能な出力の例を次に示します。

#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

エンコーダーの説明:

$_.=$"             # 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

私はこの\K仕事の使い方が本当にうれしかったです。置換する場所を指定し、ループ内に配置すると、最後のループ反復での発生がカウントされるようです。だから、s/(.*?\K,){$a}/\n/gフォームの最小の長さの文字列に一致します何もコンマ何もコンマ... 何も持ってカンマ、$aカンマが、しかし、試合の実際の交換した部品は、単に最後のコンマになります。これは、すべての$aコンマを改行で置き換える効果があり、画像の四角形を与えます。

この課題に対するPerlの大きな利点(組み込みの文字列から16進数へのコンバータは非常に便利でした)以外に、非常に短いデコーダ(実際には、Perlは16進数を文字列に変換する場合、それを使用しない方が短い)。仕組みは次のとおりです。

$\.=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"

英数字以外の文字の直前にある2つの文字の唯一のインスタンスは、コンマと改行の直前に表示される青いチャネル(アンパックする)です。そして、#最初の文字よりも前に現れる2つの文字。後者のカテゴリの一致は望ましくありませんが、それらは前者のカテゴリと重複することは避けられないため、重複する一致チェックによって除外されます。


1

MySQL、438 + 237 = 675バイト

出力の最後に末尾の改行がありますが、復号化された後は表示されません。16進関数(整数のオーバーロード)は先頭の0を切り捨てるので、文字列0で埋める必要がありました。区切り文字の間で両方の関数を宣言できれば、バイトを節約できます。

暗号化

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 ;

復号化

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 ;

使用法:

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

1

C#、312 + 142 = 454バイト

エンコーディング:

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

デコード:

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(' ');};

完全なプログラム:

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

1

Mathematica、111 + 65 = 176バイト

エンコーダー

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

デコーダ

StringTrim[""<>FromCharacterCode@ImageData[#,"Byte"][[;;,;;,3]]]&

1

処理、220 209 194 + 171 167 151 = 391 380 376 361 345バイト

更新:

役に立たないものnoStroke()を削除し、両方のforループを1文にしました。

役に立たない削除しimage(p,0,0);、復号器にパラメータとしてファイル名を与えました

暗号化アルゴリズム

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

関数を呼び出す: g("Programming Puzzles and Code Golf");

これは、文字列を取り込んで、出力を作成してからとして保存する関数ですt.png。このred値を使用して、非表示のテキストを保存します。

復号化アルゴリズム

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(" +$",""));}

関数を呼び出す: u(file_name);

これは、パラメーターで指定された画像を検索し、非表示の文字列を出力する関数でもあります(文字列を返すよりも短いため)。

拡張コード

(暗号化アルゴリズム)

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

文字列は、関数が呼び出されたときに渡されます。関数の最初の行は、平方根をとることにより、正方形の辺の長さを計算しceilます。次にforループに入りstroke、文字のASCII値を赤、青と緑にランダム値を設定する(エッジの色)を設定します。これを行った後rect、幅= 1と高さ= 1(ピクセル)を使用して(長方形)を作成します(奇妙な理由により、point適切に使用できません)。最後の行では、結果の画像がとして保存されt.pngます。

(復号化アルゴリズム)

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(" +$",""));
}

この関数は、ファイル名をパラメーターとして(文字列として)持っています。次に、ファイル内の画像は、後で使用するために変数に保存されます。それが完了し""たら、非表示の文字列を保持するためだけに新しい文字列を作成するのではなく、文字列をに設定します。次に、2つのネストされたforループを介して画像を反復処理し、ピクセルの赤の値の文字値を文字列に追加します。最後に、先頭のスペースを削除した後、結果の文字列を出力します(正規表現を使用)。非表示のテキストを返すのではなく印刷する理由は、この方法がより短く、バイトを節約するためです。


暗号化されたチャレンジ生テキスト:

ここに画像の説明を入力してください


1

Jelly、40 + 20 = 60バイトのJellyのコードページ

エンコーダー(テキスト→画像):

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

オンラインでお試しください!

デコーダー(画像→テキスト):

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

オンラインでお試しください!

プログラムが生成する可能性のある出力例(赤チャネルに情報を保存します):

#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

これらの大きな課題では、Jellyの簡潔さが少し低下し始め、構文解析のあいまいさを解決するためにいくつかの「構造」文字が必要になりますが、それでも非常に簡潔です。エンコーダの仕組みは次のとおりです。

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

デコーダーの仕組みは次のとおりです。

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.