Terapkan kunci sandi ini


13

Terapkan kunci sandi ini

Tujuan

Gunakan algoritma (dijelaskan di bagian Algoritma) untuk mengimplementasikan cipher tertentu.

Program harus membaca input dari STDIN atau yang setara terdekat yang tersedia, gunakan algoritma untuk menghasilkan ciphertext dan kunci.

Ciphertext dan kunci akan ditulis ke STDOUT atau setara terdekat yang tersedia. Format apa pun diperbolehkan, selama itu output ciphertext dan kunci.

Algoritma

Konversi karakter dalam string menjadi nilai ASCII masing-masing. Sebagai contoh:

Hello -> 72 101 108 108 111

Selanjutnya, Anda harus membuat kunci selama string dengan angka acak di kisaran 0-9.

Hello -> 62841

Tambahkan bilangan bulat dalam urutan angka acak ke nilai ASCII dari string. Dalam contoh di atas, 72 akan menjadi 78, dan 101 akan menjadi 104.

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

Selanjutnya, ubah nilai-nilai baru kembali ke karakter. Dalam contoh di atas, teks Hellomenjadi Ngtpp.

Contohnya

(Ini hanya contoh dari apa output mungkin terlihat seperti. Output dapat dan akan bervariasi.)

Hello World

Lfrlu)_supg
41606984343

This will be encoded

Zhjs$~koo gj$iuhofgj
60104723305544750226

Aturan

  • Anda dapat mengasumsikan bahwa input hanya akan berisi karakter dalam rentang az, AZ, dan spasi.
  • Pengajuan harus berupa program atau fungsi lengkap.
  • Pengajuan akan dicetak dalam byte.
  • Celah standar dilarang.
  • Ini kode-golf, jadi kode terpendek menang.

(Ini adalah salah satu tantangan pertama saya, jika ada yang salah dengan itu, jangan ragu untuk memberi tahu saya bagaimana saya bisa memperbaikinya.)


5
Tantangan ini terlihat baik bagi saya, kecuali beberapa pemikiran. 1. Apakah fungsi diizinkan alih-alih program penuh? Pertanyaan terkait adalah dapatkah nilai dikembalikan dan bukannya dicetak? 2. Anda mengatakan preferably with the format (ciphertext)\n(key)."fitur yang disukai" dan golf kode tidak bercampur dengan baik. Anda harus membuat itu wajib atau mengizinkan format output lainnya. 3. Apakah kunci harus dicetak tanpa spasi? Bagaimana dengan mencetaknya dalam format daftar, misalnya [0, 5, 2, ...]?
James

Bisakah kunci memiliki angka nol di depan?
TheBikingViking

1
Tantangan pertama yang bagus tapi saya tidak begitu yakin dengan format IO yang ketat. Biasanya fungsi diizinkan dan biasanya jawaban dapat membaca dari salah satu metode IO yang diterima. Ini termasuk menghasilkan array dengan item
Downgoat

1
Apakah angka kunci harus dihasilkan dengan distribusi yang seragam?
Dennis

1
Eh ... 101 + 2 adalah 103, bukan 104. :-)
YetiCGN

Jawaban:


5

Jelly , 12 9 byte

⁵ṁX€’Ṅ+OỌ

Cobalah online!

Bagaimana itu bekerja

⁵ṁ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 byte

Terima kasih kepada @Rod untuk menunjukkan bug

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)

Fungsi yang mengambil input melalui argumen sebagai string dan mencetak ke STDOUT.

Bagaimana itu bekerja

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

Cobalah di Ideone


generator kunci Anda tidak menghasilkan kunci yang dimulai dengan 0. meningkatkan batas dengan faktor 10 dan menghapus digit pertama harus diperbaiki: m=10**len(x);k=str(randint(m,m*10))[1:];dan Anda bahkan menyimpan byte dalam proses c:
Rod

@Rod Terima kasih telah menunjukkan bug. Itu tidak akan menyimpan byte, karena randintinklusif, artinya Anda perlu melakukannya m*10-1. Saya baru saja memikirkan cara untuk memperbaikinya untuk jumlah byte yang sama.
TheBikingViking


3

Sebenarnya, 17 byte

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

Cobalah online!

Penjelasan:

;`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 byte

"10r*]v!kGy+c

Outputnya terlihat seperti ini:

9 5 8 2 1
Qjtnp

Cobalah online!

Penjelasan:

"    ]          % 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

Saya tidak yakin apakah itu format yang tepat ...
Leaky Nun

@ Nun Leaky Aku sedikit mengubah aturan.
m654

@ m654 Di mana Anda bilang bisa ada spasi di antara nilai?
Leaky Nun

@ LeakyNun Awalnya ada aturan terhadap mereka, tetapi saya menghapusnya.
m654

1
Ide bagus menggunakan loop. Ini sebenarnya lebih pendek dari versi multi-input ratauYr
Luis Mendo

2

PowerShell v2 +, 79 77 byte

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

Mengambil input $n, memutar setiap karakter dan mendapatkan Randomelemen dari 0..9setiap iterasi. Menyimpan angka-angka itu (sebagai array) ke dalam $x. Pipa array itu ke loop lain. Setiap iterasi, mengambil elemen saat ini $_, menambahkannya ke char posisi yang diiris dari $n(cast char-to-int implisit), kemudian cast kembali sebagai [char]. Meninggalkan itu di saluran pipa. Itu diringkas dalam parens dan diedit -joinbersama untuk membentuk kata. Tersisa di saluran pipa. Selain itu, nomor $xtersebut juga -joindiedit bersama dan dibiarkan di dalam pipa. Mereka dicetak secara implisit dengan aWrite-Output pada akhir eksekusi, yang mengakibatkan mereka dicetak dengan baris baru secara default.

Contoh

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

2

C #, 252 247 245 232 216 Bytes

Ukurannya sangat buruk dibandingkan dengan solusi lain tetapi ...

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

Ini adalah jawaban kedua saya untuk codegolf dan saya cukup pemula mempertimbangkan C # jadi saya akan senang mendengar bagaimana membuatnya lebih pendek :)

Tidak Disatukan:

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);
    }
}
  • Disimpan 5 Bytes berkat @FryAmTheEggman
  • Disimpan 2 Bytes berkat @theLambGoat
  • Disimpan 7 Bytes dengan menghapus staticdari p kelas
  • Disimpan 24 Bytes berkat @milk

1
Triknya adalah tidak membandingkan dengan bahasa lain;) Saya tidak terlalu berpengalaman dalam C # golf, tetapi dapatkah Anda melakukan b++<i.Count()dan membiarkan klausa ketiga kosong? Juga, saya rasa Anda tidak perlu mengekor baris baru, jadi panggilan terakhir untuk WriteLinemenjadi Writesebaliknya.
FryAmTheEggman

Saya juga tidak berpengalaman dalam C # tapi saya pikir Anda dapat memindahkan = r.Berikutnya (10) hingga deklarasi d dan menyimpan pada set kurung dalam penulisan. Atau apakah random tidak mengembalikan int sehingga Anda tidak bisa melakukan itu?
theLambGoat

Saya pikir saya bisa melakukan itu, biarkan saya periksa
Tom Doodler

Anda dapat mengganti jenis dengan var. yaitu- var c=bukannyastring c= mencukur beberapa byte.
susu

Mengapa tidak meninggalkan hasil Console.ReadLine()sebagai string? i.Lengthlebih pendek dari i.Count(), Anda tidak perlu System.Linq. string memiliki pengindeks char. Juga menciptakan Acak baru objek dalam lingkaran kurang byte: new Random().Next(10).
susu

2

CJam, 11 byte

Nq{Amr_o+}/

Cobalah online!

Bagaimana itu bekerja

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

05AB1E , 18 17 byte

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

Penjelasan

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

Cobalah online


2

Python 3, 112 byte

c adalah fungsi yang mengembalikan teks dan kunci terenkripsi

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

Berikut adalah kode yang melakukan hal yang sama dan sedikit lebih mudah dibaca

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

Keluaran:

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

Selamat datang di situs ini!
James

1

PHP, 63 86 82 byte

Edit: lupa mencetak kunci ...

Terima kasih kepada Alex Howansky karena telah menyelamatkan saya 4 byte.

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

Input diberikan melalui argumen baris perintah. Mengambil setiap karakter dalam string dan menambahkan int acak dari 0-9 ke kode ASCII-nya, lalu mengonversi kode kembali ke ASCII. Setiap nomor acak ditambahkan $s, yang dicetak di bagian akhir.


Anda perlu mencetak kunci juga.
Alex Howansky

Anda dapat menempatkan $s.=$rsetelah semi ke-2 di dalam for loop, menyimpan byte karena Anda dapat membuang semi trailing-nya. Maka loop Anda hanya akan menjadi satu pernyataan sehingga Anda dapat memotong kawat pembungkus, menghemat 2 byte lebih. Kemudian pada akhirnya, Anda bisa meletakkan bagian $sdalam string yang dikutip menyimpan .operator untuk satu byte lagi. :)
Alex Howansky

@AlexHowansky: Itu sangat benar. Terima kasih
Bisnis Cat

1

J, 32 byte

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

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

1

Perl, 34 byte

Termasuk +1 untuk -p

#!/usr/bin/perl -p
s%.%$\.=$==rand 10;chr$=+ord$&%eg

0

Perl, 65 byte

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

Butuh beberapa saat untuk mencari cara mendapatkan input tanpa baris baru di akhir. Mengambilnya sebagai baris perintah arg


Solusi Anda memiliki beberapa masalah. Input tidak dibaca dari bentuk STDIN, $;jangan mulai kosong sehingga ia mencetak konten lama dan rand tidak pernah dapat menghasilkan 9. Mereka mudah diperbaiki dan menggunakan STDIN akan membuat kode Anda lebih pendek :-)
Ton Hospel

@TonHospel Biasanya persyaratan input longgar dan args dapat diterima atas STDIN dan saat mengambil input dari STDIN lebih pendek, harus menghapus baris baru dari itu membuatnya lebih lama. Dan sementara rand menghasilkan angka <9, metode int Perl lebih baik daripada lantai jadi apa pun> = 8,5 harus berakhir sebagai 9
theLambGoat

Persyaratan input biasanya longgar, tetapi tidak. Mendapatkan non baris baru dari STDIN mudah: <>=~/./g. Dan tidak, intdalam perl memotong menuju 0, itu tidak bulat. perl -wle 'print int 8.6'keluaran8
Ton Hospel

0

Python 2, 84 99 byte

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

Menggunakan id()nilai string untuk menghasilkan angka acak.

Cobalah


Anda harus menampilkan kunci dan juga ciphertext.
TheBikingViking

@ TheBikingViking tidak tahu bagaimana saya melewatkan itu. Terima kasih - sudah diperbaiki
atlasologis

Saya pikir ini juga memiliki masalah yang sama dengan versi sebelumnya dari jawaban Python saya; itu tidak pernah menghasilkan kunci dengan nol terkemuka.
TheBikingViking

@TheBikingViking Diperbaiki lagi
atlasologist

ubah map(chr,[ord(a)+int(b)for a,b in zip(x,y)])menjadi map(lambda x,y:chr(ord(x)+int(y)),x,y)? yang seharusnya menyimpan sesuatu
ljeabmreosn

0

Senva , 74 byte

Ini adalah program terpendek yang saya buat:

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

Sedikit penjelasan? (Catatan: BM berarti Memori Kembali ):

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

Itu tampak lebih besar sekarang, benar: p? Mungkin dimungkinkan untuk mengoptimalkan kode ini, tetapi untuk saat itu terpendek yang saya temukan.


0

C #, 174 byte

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

Tidak Disatukan:

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

Sangat mudah, sungguh.


0

Perl 6: 55 atau 70 byte

Sebagai fungsi anonim yang mengambil parameter string, dan mengembalikan daftar dua string (54 karakter, 55 byte) :

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

Sebagai program yang membaca dari STDIN dan menulis ke STDOUT (69 karakter, 70 byte) :

my @a=get.ords;my @n=^9 .roll(@a);say (@a Z+@n)».chr.join;say @n.join
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.