Thực hiện mật mã khóa này


13

Thực hiện mật mã khóa này

Mục tiêu

Sử dụng thuật toán (được giải thích trong phần Thuật toán) để thực hiện một mật mã nhất định.

Chương trình phải đọc đầu vào từ STDIN hoặc tương đương có sẵn gần nhất, sử dụng thuật toán để tạo bản mã và khóa.

Bản mã và khóa sẽ được ghi vào STDOUT hoặc tương đương có sẵn gần nhất. Bất kỳ định dạng nào đều được cho phép, miễn là nó xuất ra bản mã và khóa.

Thuật toán

Chuyển đổi các ký tự trong chuỗi thành các giá trị ASCII tương ứng. Ví dụ:

Hello -> 72 101 108 108 111

Tiếp theo, bạn sẽ cần tạo một khóa miễn là chuỗi có số ngẫu nhiên trong phạm vi 0-9.

Hello -> 62841

Thêm các số nguyên trong chuỗi số ngẫu nhiên vào các giá trị ASCII của chuỗi. Trong các ví dụ trên, 72 sẽ trở thành 78 và 101 sẽ trở thành 104.

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

Tiếp theo, chuyển đổi các giá trị mới trở lại ký tự. Trong các ví dụ trên, văn bản Hellođã trở thành Ngtpp.

Ví dụ

(Đây là những ví dụ đơn giản về hình thức đầu ra có thể trông như thế nào. Đầu ra có thể và sẽ thay đổi.)

Hello World

Lfrlu)_supg
41606984343

This will be encoded

Zhjs$~koo gj$iuhofgj
60104723305544750226

Quy tắc

  • Bạn có thể giả sử rằng đầu vào sẽ chỉ chứa các ký tự trong phạm vi az, AZ và khoảng trắng.
  • Đệ trình phải là chương trình hoặc chức năng đầy đủ.
  • Đệ trình sẽ được tính bằng byte.
  • Sơ hở tiêu chuẩn bị cấm.
  • Đây là môn đánh gôn, vì vậy đoạn mã ngắn nhất sẽ thắng.

(Đây là một trong những thử thách đầu tiên của tôi, nếu có điều gì đó không ổn với nó, vui lòng cho tôi biết làm thế nào tôi có thể cải thiện nó.)


5
Thử thách này có vẻ tốt với tôi, ngoại trừ một vài suy nghĩ. 1. Là một chức năng được phép thay vì một chương trình đầy đủ? Một câu hỏi liên quan là các giá trị có thể được trả lại thay vì in không? 2. Bạn đã nói preferably with the format (ciphertext)\n(key)."các tính năng ưa thích" và mã golf không kết hợp tốt với nhau. Bạn nên làm điều đó bắt buộc hoặc cho phép các định dạng đầu ra khác. 3. Phím có phải được in không có dấu cách không? Điều gì về việc in nó ở định dạng danh sách, ví dụ [0, 5, 2, ...]?
DJMcMayhem

Chìa khóa có thể có số không hàng đầu?
TheBikingViking 19/8/2016

1
Thử thách đầu tiên rất hay nhưng tôi không chắc lắm về các định dạng IO nghiêm ngặt. Thông thường các hàm được cho phép và thường câu trả lời có thể đọc từ một trong các phương thức IO được chấp nhận. Điều này bao gồm xuất ra một mảng với các mặt hàng
Downgoat

1
Các chữ số của khóa có phải được tạo với phân phối đồng đều không?
Dennis

1
À ... 101 + 2 là 103, không phải 104. :-)
YetiCGN

Câu trả lời:


5

Thạch , 12 9 byte

⁵ṁX€’Ṅ+OỌ

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

Làm thế nào nó hoạt động

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

Cảm ơn @Rod đã chỉ ra một lỗi

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)

Một hàm lấy đầu vào thông qua đối số dưới dạng chuỗi và in ra STDOUT.

Làm thế nào nó hoạt động

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

Hãy thử nó trên Ideone


máy phát điện chính của bạn không tạo ra các phím bắt đầu với 0. tăng ranh giới với hệ số 10 và loại bỏ các chữ số 1 nên sửa chữa: m=10**len(x);k=str(randint(m,m*10))[1:];và thậm chí bạn tiết kiệm một byte trong quá trình c:
Rod

@Rod Cảm ơn bạn đã chỉ ra lỗi. Điều đó sẽ không lưu bất kỳ byte nào, tuy nhiên, vì đã randintbao gồm, có nghĩa là bạn sẽ cần phải làm m*10-1. Tôi vừa nghĩ ra một cách để sửa nó cho cùng một số byte.
TheBikingViking 19/8/2016


3

Trên thực tế, 17 byte

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

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

Giải trình:

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

Đầu ra trông như thế này:

9 5 8 2 1
Qjtnp

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

Giải trình:

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

Tôi không chắc đó có phải là định dạng đúng không ...
Leaky Nun

@Leaky Nun Tôi đã thay đổi các quy tắc một chút.
m654

@ m654 Nơi mà bạn nói có thể có khoảng trắng giữa các giá trị?
Nữ tu bị rò rỉ

@LeakyNun Ban đầu có một quy tắc chống lại họ nhưng tôi đã gỡ bỏ nó.
m654

1
Ý tưởng tốt để sử dụng các vòng lặp. Nó thực sự ngắn hơn phiên bản nhiều đầu vào của rhoặcYr
Luis Mendo

2

PowerShell v2 +, 79 77 byte

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

Đưa đầu vào $n, vòng lặp trên mỗi ký tự và nhận một Randomphần tử từ 0..9mỗi lần lặp. Lưu trữ những số đó (dưới dạng một mảng) vào $x. Ống đó mảng vào một vòng lặp khác. Mỗi lần lặp, lấy phần tử hiện tại $_, thêm nó vào char vị trí được cắt ra $n(diễn viên char-to-int ẩn), sau đó nhập lại dưới dạng [char]. Lá đó trên đường ống. Điều đó được gói gọn trong parens và -joined với nhau để tạo thành từ. Đó là trái trên đường ống. Ngoài ra, số $xcũng được -joined với nhau và để lại trên đường ống. Chúng được in ngầmWrite-Output phần cuối của việc thực thi, kết quả là chúng được in với một dòng mới theo mặc định.

Thí dụ

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

2

C #, 252 247 245 232 216 byte

Kích thước khá tệ so với các giải pháp khác nhưng tuy nhiên ...

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

Đây là câu trả lời thứ hai của tôi cho một codegolf và tôi là người mới bắt đầu xem xét C # vì vậy tôi rất trân trọng khi nghe cách làm cho nó ngắn hơn :)

Ung dung:

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);
    }
}
  • Đã lưu 5 byte nhờ @FryAmTheEggman
  • Đã lưu 2 byte nhờ @theLambGoat
  • Đã lưu 7 byte bằng cách xóa statickhỏi lớp p
  • Đã lưu 24 Byte nhờ @milk

1
Bí quyết là không so sánh với các ngôn ngữ khác;) Tôi không rành về golf C #, nhưng bạn có thể làm b++<i.Count()và để trống mệnh đề thứ ba không? Ngoài ra, tôi không nghĩ rằng bạn cần một dòng mới, vì vậy cuộc gọi cuối cùng WriteLinecó thể được Writethay thế.
FryAmTheEggman

Tôi cũng không rành về C # nhưng tôi nghĩ bạn có thể di chuyển = r. Tiếp theo (10) lên khai báo d và lưu vào một dấu ngoặc đơn trong ghi. Hoặc ngẫu nhiên không trả về một int để bạn không thể làm điều đó?
theLambGoat

Tôi nghĩ rằng tôi có thể làm điều đó, hãy để tôi kiểm tra
Tom Doodler

Bạn có thể thay thế các loại với var. tức là- var c=thay vì string c=cạo một vài byte.
sữa

Tại sao không để lại kết quả Console.ReadLine()như chuỗi? i.Lengthngắn hơn i.Count(), bạn sẽ không cần System.Linq. chuỗi có một bộ chỉ mục char. Ngoài ra, việc tạo các đối tượng Ngẫu nhiên mới trong vòng lặp có ít byte hơn : new Random().Next(10).
sữa

2

CJam, 11 byte

Nq{Amr_o+}/

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

Làm thế nào nó hoạt động

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¶?,

Giải trình

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

Dùng thử trực tuyến


2

Python 3, 112 byte

c là một hàm trả về văn bản được mã hóa và khóa

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

Đây là một mã làm điều tương tự và dễ đọc hơn một chú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

Đầu ra:

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

Chào mừng đến với trang web này!
DJMcMayhem

1

PHP, 63 86 82 byte

Chỉnh sửa: quên in khóa ...

Cảm ơn Alex Howansky đã tiết kiệm cho tôi 4 byte.

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

Đầu vào được đưa ra thông qua một đối số dòng lệnh. Lấy từng ký tự trong chuỗi và thêm một int ngẫu nhiên từ 0-9 vào mã ASCII của nó, sau đó chuyển đổi mã trở lại ASCII. Mỗi số ngẫu nhiên được thêm vào $s, được in ở cuối.


Bạn cần phải in chìa khóa là tốt.
Alex Howansky

Bạn có thể đặt dấu $s.=$rsau bán thứ 2 vào vòng lặp for, tiết kiệm một byte vì bạn có thể bỏ dấu bán phần của nó. Sau đó, vòng lặp của bạn sẽ chỉ là một câu lệnh để bạn có thể cắt bỏ các dấu ngoặc nhọn, tiết kiệm thêm 2 byte. Sau đó, ở cuối, bạn có thể đặt $sbên trong chuỗi trích dẫn lưu .toán tử cho thêm một byte. :)
Alex Howansky

@AlexHowansky: Điều đó rất đúng. Cảm ơn
Mèo kinh doanh

1

J, 32 byte

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

trăn tương đương:

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

Bao gồm +1 cho -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$;"

Mất một lúc tôi mới tìm ra cách lấy đầu vào mà không có dòng mới ở cuối. Làm cho nó như là một dòng lệnh arg


Giải pháp của bạn có một số vấn đề. Đầu vào không được đọc mẫu STDIN, $;không bắt đầu trống nên nó in nội dung cũ và rand không bao giờ có thể tạo 9. Chúng rất dễ sửa và sử dụng STDIN sẽ làm cho mã của bạn ngắn hơn :-)
TonMedel 23/8/2016

@TonH Phúc Thông thường các yêu cầu đầu vào lỏng lẻo và các đối số có thể chấp nhận được trên STDIN và trong khi lấy đầu vào từ STDIN thì ngắn hơn, phải xóa dòng mới khỏi nó khiến nó dài hơn. Và trong khi rand tạo ra các số <9, phương thức int của Perl sẽ làm tròn chứ không phải sàn nên mọi thứ> = 8,5 sẽ kết thúc bằng 9
theLambGoat

Yêu cầu đầu vào thường lỏng lẻo, nhưng ở đây thì không. Nhận phi tuyến mới từ STDIN thật dễ dàng : <>=~/./g. Và không, inttrong perl cắt ngắn về 0, nó không tròn. perl -wle 'print int 8.6'đầu ra8
TonMedel 23/8/2016

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

Sử dụng id()giá trị của chuỗi để tạo số ngẫu nhiên.

Thử nó


Bạn phải xuất khóa cũng như bản mã.
TheBikingViking 19/8/2016

@TheBikingViking không biết làm thế nào tôi bỏ lỡ điều đó. Cảm ơn - đã sửa
nghiên

Tôi nghĩ rằng điều này cũng có vấn đề tương tự như phiên bản trước của câu trả lời Python của tôi; nó không bao giờ tạo ra các khóa với các số 0 đứng đầu.
TheBikingViking 19/8/2016

@TheBikingViking Đã sửa một lần nữa
đồ học

đổi map(chr,[ord(a)+int(b)for a,b in zip(x,y)])thành map(lambda x,y:chr(ord(x)+int(y)),x,y)? điều đó sẽ tiết kiệm một cái gì đó
ljablesmreosn

0

Senva , 74 byte

Đây là chương trình ngắn nhất tôi đã thực hiện:

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

Một lời giải thích nhỏ? (Lưu ý: BM có nghĩa là Bộ nhớ lại ):

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

Điều đó xuất hiện lớn hơn bây giờ, đúng không? Có thể bạn có thể tối ưu hóa mã này, nhưng hiện tại đó là thời gian ngắn nhất tôi tìm thấy.


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

Ung dung:

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

Khá đơn giản, thực sự.


0

Perl 6: 55 hoặc 70 byte

Là một hàm ẩn danh nhận tham số chuỗi và trả về danh sách hai chuỗi (54 ký tự, 55 byte) :

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

Là một chương trình đọc từ STDIN và ghi vào STDOUT (69 ký tự, 70 byte) :

my @a=get.ords;my @n=^9 .roll(@a);say (@a Z+@n)».chr.join;say @n.join
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.