このキー暗号を実装する


13

このキー暗号を実装する

ゴール

アルゴリズム(「アルゴリズム」セクションで説明)を使用して、特定の暗号を実装します。

プログラムは、STDINまたは利用可能な最も近い同等物から入力を読み取り、アルゴリズムを使用して暗号文とキーを生成する必要があります。

暗号文とキーは、STDOUTまたは利用可能な最も近いものに書き込まれます。暗号文とキーを出力する限り、任意の形式が許可されます。

アルゴリズム

文字列内の文字をそれぞれのASCII値に変換します。例えば:

Hello -> 72 101 108 108 111

次に、0〜9の範囲の乱数を含む文字列である限り、キーを生成する必要があります。

Hello -> 62841

乱数列の整数を文字列のASCII値に追加します。上記の例では、72は78にな​​り、101は104になります。

72 + 6 = 78, 101 + 2 = 103, 108 + 8 = 116, etc

次に、新しい値を文字に戻します。上記の例では、テキストHelloはになっていNgtppます。

(これらは出力どのように見えるかの単なる例です。出力は変化する可能性があります。)

Hello World

Lfrlu)_supg
41606984343

This will be encoded

Zhjs$~koo gj$iuhofgj
60104723305544750226

ルール

  • 入力には、az、AZ、およびスペースの範囲の文字のみが含まれると想定できます。
  • 提出は完全なプログラムまたは機能でなければなりません。
  • 提出物はバイト単位で記録されます。
  • 標準的な抜け穴は禁止されています。
  • これはコードゴルフなので、最短のコードが優先されます。

(これは私の最初の課題の1つです。何か問題がある場合は、改善方法を教えてください。)


5
この挑戦は、いくつかの考えを除いて、私には良さそうです。1.完全なプログラムの代わりに機能が許可されていますか?関連する質問は、値を印刷する代わりに返すことができますか?2. preferably with the format (ciphertext)\n(key).「好みの機能」とコードゴルフはあまりうまく調和しないと言われました。これを必須にするか、他の出力形式を許可する必要があります。3.キーはスペースなしで印刷する必要がありますか?リスト形式で印刷するのはどう[0, 5, 2, ...]ですか?
ジェームズ

キーの先頭にゼロを付けることはできますか?
TheBikingViking

1
ナイスな最初の挑戦ですが、厳密なIOフォーマットについてはよくわかりません。通常、関数は許可され、通常、受け入れられたIOメソッドの1つから回答を読み取ることができます。これには、アイテムを含む配列の出力が含まれます
-Downgoat

1
キーの数字は均一な分布で生成する必要がありますか?
デニス

1
ええと... 101 + 2は104ではなく103です。:-)
YetiCGN

回答:


5

ゼリー12 9 バイト

⁵ṁX€’Ṅ+OỌ

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

使い方

⁵ṁX€’Ṅ+OỌ  Main link. Argument: s (string)

⁵             Set the return value to 10.
 ṁ            Mold; create an array of 10's with the length of s.
  X€          Pseudo-randomly pick a integer between 1 and 10, for each 10.
    ’         Decrement, so the integers fall in the range [0, ..., 9].
     Ṅ        Print the key, as an array, followed by a linefeed.
      +O      Add the integers to the ordinals (code points) of s.
        Ọ     Unordinal; convert back to characters.

5

Python 3、130バイト

バグを指摘してくれた@Rodに感謝

from random import*
def f(x):l=10**len(x);k=str(randint(0,l-1)+l)[1:];print(''.join(chr(ord(i)+int(j))for i,j in zip(x,k))+'\n'+k)

引数を介して入力を文字列として受け取り、STDOUTに出力する関数。

使い方

from random import*  Import everything from the random module
def f(x):            Function with input string x
l=10**len(x)         Define l for later use as 10^length(x)
randint(0,l-1)+l     Generate a random integer in the range [0, l-1] and add l, giving a
                     number with l+1 digits...
k=str(...)[1:]       ...convert to a string and remove the first character, giving a key of
                     length l that can include leading zeroes, and store in k
for i,j in zip(x,k)  For each character pair i,j in x and k:
chr(ord(i)+int(j))    Find the UTF-8 code-point (same as ASCII for the ASCII characters),
                      add the relevant key digit and convert back to character
''.join(...)         Concatenate the characters of the ciphertext
print(...+'\n'+k)    Add newline and key, then print to STDOUT

Ideoneでお試しください


キージェネレーターは、0で始まるキーを生成しません。境界を10倍に増やし、1桁目を削除する必要がm=10**len(x);k=str(randint(m,m*10))[1:];あります。さらに、プロセスcでバイトを保存しますc:
Rod

@Rodバグを指摘してくれてありがとう。ただし、randint包括的であるため、バイトを節約できませんm*10-1。つまり、を実行する必要があります。私はちょうど同じバイト数のためにそれを修正する方法を考えました。
TheBikingViking


3

実際には、17バイト

;`X9J`M;(O¥♂cΣ@εj

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

説明:

;`X9J`M;(O¥♂cΣ@εj
;                  dupe input
 `X9J`M            for each character in input copy:
  X9J                discard the character, push a random integer in [0, 9]
       ;           duplicate the offset array
        (O         bring input to top of stack, ordinal array
          ¥♂c      pairwise addition with offset array, turn each ordinal into a character
             Σ     concatenate
              @εj  concatenate the copy of the offset array


2

MATL、13バイト

"10r*]v!kGy+c

出力は次のようになります。

9 5 8 2 1
Qjtnp

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

説明:

"    ]          % For each character:
 10             % Push a 10 onto the stack
   r            % Push a random float in [O, 1)
    *           % Multiply. This essentially the same thing as pushing a number in [0, 10)
      v!k       % Join all of these together, and take the floor
         G      % Push the input again
          y     % Duplicate the array of random numbers
           +    % And add these together. Since MATL treats strings as an array of chars, we don't need to explicitly convert types
            c   % Display as string

それは適切なフォーマットだ場合、私は...よく分からない
漏れ修道女

@Leaky Nunルールを少し変更しました。
m654

@ m654値の間にスペースを入れることができると言った場所はどこですか?
リーキー修道女

@LeakyNunもともと彼らに対するルールがありましたが、私はそれを削除しました。
m654

1
ループを使用することをお勧めします。それは実際に複数入力バージョンのrまたはより短いですYr
ルイスメンドー

2

PowerShell v2 +、79 77バイト

param($n)-join(($x=[char[]]$n|%{0..9|Random})|%{[char]($_+$n[$i++])});-join$x

入力を受け取り$n、すべての文字をループしRandom0..9各反復から要素を取得します。それらの数値を(配列として)に格納し$xます。その配列を別のループにパイプします。各反復は、現在の要素を取り、$_それを$n(暗黙的なchar-to-intキャスト)から切り取った位置charに追加し、次にとして再キャストし[char]ます。パイプラインに残します。それは括弧にカプセル化され、-join一緒に編集されて単語を形成します。それはパイプラインに残っています。さらに、番号$x-join一緒に編集され、パイプラインに残されます。これらはWrite-Output実行の最後に暗黙的に印刷され、デフォルトで改行で印刷されます。

PS C:\Tools\Scripts\golfing> .\implement-this-key-cipher.ps1 'Hello World!'
Lhoot(Yt{mf"
433358259121

2

C位、252 247 245 232 216のバイト

サイズは他のソリューションに比べてかなり悪いですが、それでも...

using System;using System.Linq;class p{static void Main(){var c="";var i=Console.ReadLine();var r=new Random();for(int b=0;b++<i.Count();){int d=r.Next(10);Console.Write((char)(i[b]+d));c+=d;}Console.Write("\n"+c);}}

これはcodegolfに対する私の2番目の回答であり、私はC#を検討している初心者なので、短くする方法を聞いていただければ幸いです:)

ゴルフをしていない:

using System;
using System.Linq;

class p
{
    static void Main()
    {
        var c = "";
        var i = Console.ReadLine();
        var r = new Random();
        for (int b = 0; b++ < i.Count();)
        {
            int d = r.Next(10);
            Console.Write((char)(i[b] + d));
            c += d;
        }
        Console.Write("\n" + c);
    }
}
  • @FryAmTheEggmanのおかげで5バイト節約
  • @theLambGoatのおかげで2バイト節約
  • 削除して7バイトを保存 staticクラスpからして
  • @milkのおかげで24バイト節約

1
トリックは、他の言語と比較することではありません;)私はC#ゴルフに特に精通しているわけではありませんがb++<i.Count()、3番目の句を空にしておくことができますか?また、末尾の改行が必要だとは思わないので、最後の呼び出しWriteLineWrite代わりにできます。
FryAmTheEggman

私はC#にも精通していませんが、= r.Next(10)をdの宣言まで移動し、書き込みの括弧のセットを保存できると思います。または、ランダムはintを返さないので、それを行うことはできませんか?
theLambGoat

私はそれができると思います、私にチェックさせてください
トム・ドドルラー

タイプをに置き換えることができますvar。すなわち、数バイトを削るvar c=代わりにstring c=
ミルク

の結果をConsole.ReadLine()文字列のままにしてみませんか?i.Lengthがより短い場合i.Count()、System.Linqは必要ありません。文字列にはcharインデクサーがあります。また、ループ内に新しいRandomオブジェクトを作成すると、バイト数が少なくなりますnew Random().Next(10)
ミルク

2

CJam、11バイト

Nq{Amr_o+}/

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

使い方

N            Push a linefeed on the stack.
 q           Read all input from STDIN and push it on the stack.
  {      }/  For each character in the input:
   Amr       Pseudo-randomly pick an integer in [0 ... 9].
      _o     Print a copy.
        +    Add the integer to the character.
             (implicit) Print the linefeed, followed by the modified characters.

2

05AB1E18 17バイト

vžh.RDyÇ+ç`?}J¶?,

説明

v           }      # for each char in input
 žh.RD             # push 2 copies of a random number in [0..9]
      yÇ+          # add 1 copy to the current chars ascii value
         ç`?       # convert to char, flatten and print
             J     # join stack (which contain the digits of the key)
              ¶?,  # print a newline followed by the key

オンラインで試す


2

Python 3、112バイト

cは、暗号化されたテキストとキーを返す関数です

from random import*
c=lambda t:map(''.join,zip(*[(chr(a+b),str(b))for a,b in((ord(i),randint(0,9))for i in t)]))

以下は同じことをするコードで、もう少し読みやすいです

def encrypt(text):
    # keep the codes of the letters in the input and a random key
    # that will be used later to encrypt this letter
    letter_and_key = ((ord(letter),randint(0,9)) for letter in text)

    # encrypt the letter and keep the key used as a string
    output_and_key = [(chr(letter_code+key), str(key))
                      for letter_code, key in letter_and_key]

    # At this point the values are kept in the format:
    # [(firstletter, firstkey), (secondletter, secondkey), ...]

    # to reorder the list to be able to output in the format "text key"
    text, key = map(''.join, zip(*output_and_key))

    # same as print(*output_and_key)
    return text, key

出力:

>>> text, key = c('Hello World')
>>> print(text, key, sep='\n')
Liuot#`oylk
44935390707

このサイトへようこそ!
ジェームズ

1

PHP、63 86 82バイト

編集:キーを印刷するのを忘れた...

4バイト節約してくれたAlex Howanskyに感謝します。

for(;$i<strlen($a=$argv[1]);$s.=$r)echo chr(ord($a[$i++])+$r=rand(0,9));echo"
$s";

入力は、コマンドライン引数を介して与えられます。文字列の各文字を取得し、0〜9のランダムなintをASCIIコードに追加してから、コードをASCIIに変換します。すべての乱数がに追加$sされ、最後に印刷されます。


キーも印刷する必要があります。
アレックスハワンスキー

$s.=$rforループの2番目のセミの後にセミコロンを置くと、後続のセミをダンプできるため、バイトを節約できます。その後、ループは1つのステートメントのみになるため、ラッピングブレースを切り取り、さらに2バイトを節約できます。最後に$s、引用符で囲まれた文字列内に.演算子を保存して、もう1バイト使用できます。:)
アレックスハワンスキー

@AlexHowansky:それは本当です。ありがとう
ビジネスキャット

1

J、32バイト

<@:e,:~[:<[:u:3&u:+e=.[:?[:$&10#

同等のpython:

from random import randint
def encrypt(message):
    rand_list = list(map(lambda x: randint(0, 9), range(len(message))))
    return (''.join(list(map(lambda x,y: chr(x+y), rand_list, map(ord, message)))), rand_list)


0

Perl、65バイト

for(split'',$ARGV[0]){$;.=$a=int rand 9;$b.=chr$a+ord}say"$b\n$;"

最後に改行せずに入力を取得する方法を理解するのにしばらく時間がかかりました。コマンドライン引数として受け取ります


ソリューションにはいくつかの問題があります。入力フォームSTDINが、読まれていない$;、それは古いコンテンツを出力しますので、空に起動しないとランドは、彼らはSTDINが:-)あなたのコードが短くなります使用して修正するのは簡単ですし、9を生成することはできません
トンHospel

@TonHospel通常、入力要件は緩く、引数はSTDINよりも許容されます。STDINからの入力は短くなりますが、改行を削除する必要があるため長くなります。randは9未満の数値を生成しますが、Perlのintメソッドはフロアではなく丸めるため、8.5以上は9
theLambGoat

入力要件は通常緩いですが、ここではそうではありませんでした。STDINから非改行を取得するのは簡単です<>=~/./g。いいえ、intperlでは0に向かって切り捨てられ、丸められません。perl -wle 'print int 8.6'出力8
トンホスペル

0

Python 2、84 99バイト

def f(x):y=`id(x)**len(x)`[1:len(x)+1];return''.join(map(chr,[ord(a)+int(b)for a,b in zip(x,y)])),y

id()文字列の値を使用して乱数を生成します。

それを試してみてください


キーと暗号文を出力する必要があります。
TheBikingViking

@TheBikingVikingは私がそれを見逃した方法を知りません。ありがとう-修正済み
アトラロジスト

これには、Pythonの回答の以前のバージョンと同じ問題があると思います。先行ゼロのキーは生成されません。
TheBikingViking

@TheBikingVikingが再び修正されました
アトラロジスト

に変更map(chr,[ord(a)+int(b)for a,b in zip(x,y)])map(lambda x,y:chr(ord(x)+int(y)),x,y)ますか?それは何かを救うはずです
ljeabmreosn

0

センバ、74バイト

これが私が作った最短のプログラムです:

2'(`>0.>{@}0'{v}2-2'0,{@}1'{v}0'{+}{'}9%+{^}{1-}1'"{+}{~}>$10.~0'2+"0,-:>$

少し説明?(注:BMバックメモリを意味します):

// === Input and informations storing ===

2'  // Go to the 3rd cell (the two first will be used to store informations)
(   // Ask the user for a string (it will be stored as a suite of ASCII codes)
`   // Go the end of the string
>   // Make a new cell
0.  // Put a 0 to mark the end of the string
>   // Make a new cell, here will be stored the first random number
{@} // Store its adress in BM
0'  // Go to the 1st cell
{v} // Paste the adress, now the 1st cell contains the adress of the first random number
2-  // Subtract 2 because the string starts at adress 2 (the 3rd cell)
2'  // Go to the 3rd cell (where the string begins)

// === String encryption and displaying ===

0,  // While the current cell doesn't contain 0 (while we didn't reach the string's end)
  {@}  // Store the character's adress into the memory
  1'   // Go to the 2nd cell
  {v}  // Paste the value, now the 1st cell contains the adress of the current char
  0'   // Go to the 1st cell
  {+}  // Add the adress of the first random number to the current char adress
  {'}  // Go to this adrses
  9%+  // A random number between 0 and 10
  {^}  // Store this number in BM
  {1-} // Decrease BM (random number between 0 and 9)
  1'   // Go to the 1st cell
  "    // Go to the adress pointed by the cell (the adress of the current char)
  {+}  // Add it to the random number value
  {~}  // Display it as an ASCII character
  >    // Go to the next cell (the next character)
$   // End of the loop
10. // Set the new line's ASCII code into the current cell (which is now useless, so it can be overwritten)
~   // Display the new line
0'  // Go to the first cell
2+  // Add 2 to the adress, because we are not in the string loop : we cancel the 2 substraction
"   // Go to the pointed adress (the first random number's one)

// === Display the random numbers ===

0,  // While we didn't reach the end of the random numbers suite
    // That was why I stored numbers between 1 and 10, the first equal to 0 will be the end of the suite
  - // Decrease it (number between 0 and 9)
  : // Display the current random number as an integer
  > // Go to the next cell (the next number)
$ // End of the loop

それは今より大きく見えます、true:p?このコードを最適化することは可能かもしれませんが、現時点では私が見つけた最短の時間です。


0

C#、174バイト

using static System.Console;class b{static void Main(){var c=new System.Random();var d="\n";foreach(var e in ReadLine()){var f=c.Next(10);Write((char)(e+f));d+=f;}Write(d);}}

ゴルフをしていない:

using static System.Console;

class b
{
    static void Main()
    {
        var c = new System.Random();
        var d = "\n";

        foreach (var e in ReadLine())
        {
            var f = c.Next(10);
            Write((char)(e + f));
            d += f;
        }

        Write(d);
    }
}

本当に簡単です。


0

Perl 6:55または70バイト

文字列パラメーターを受け取り、2つの文字列(54文字、55バイト)のリストを返す匿名関数として:

{my @n=^9 .roll(.ords);(.ords Z+@n)».chr.join,@n.join}

STDINから読み取り、STDOUTに書き込むプログラムとして(69文字、70バイト)

my @a=get.ords;my @n=^9 .roll(@a);say (@a Z+@n)».chr.join;say @n.join
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.