이 키 암호를 구현


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

그런 다음 새 값을 문자로 다시 변환하십시오. 위의 예에서 텍스트 HelloNgtpp입니다.

(이 단순히 출력은 무엇의 예 처럼 보인다. 출력은과 다를 수 있습니다.)

Hello World

Lfrlu)_supg
41606984343

This will be encoded

Zhjs$~koo gj$iuhofgj
60104723305544750226

규칙

  • 입력에 az, AZ 및 공백 범위의 문자 만 포함한다고 가정 할 수 있습니다.
  • 제출물은 전체 프로그램 또는 기능이어야합니다.
  • 제출물은 바이트 단위로 점수가 매겨집니다.
  • 표준 허점 은 금지되어 있습니다.
  • 이것은 코드 골프이므로 가장 짧은 코드가 승리합니다.

(이것은 내 첫 번째 도전 중 하나입니다. 문제가 있으면 개선 방법을 알려주십시오.)


5
이 도전은 몇 가지 생각을 제외하고는 나에게 좋아 보인다. 1. 전체 프로그램 대신 기능이 허용됩니까? 관련 질문은 값을 인쇄하는 대신 반환 할 수 있습니까? 2. preferably with the format (ciphertext)\n(key)."선호하는 기능"과 코드 골프는 잘 섞이지 않는다고했습니다. 필수 또는 다른 출력 형식을 허용해야합니다. 3. 공백없이 키를 인쇄해야합니까? 예를 들어 목록 형식으로 인쇄하는 것은 [0, 5, 2, ...]어떻습니까?
James

키 앞에 0을 붙일 수 있습니까?
TheBikingViking

1
좋은 첫 번째 도전이지만 엄격한 IO 형식에 대해서는 잘 모르겠습니다. 일반적으로 함수가 허용되며 일반적으로 허용 된 IO 메소드 중 하나에서 응답을 읽을 수 있습니다. 여기에는 아이템이 포함 된 어레이 출력이 포함됩니다
Downgoat

1
균일 한 분포로 키의 숫자를 생성해야합니까?
Dennis

1
어 ... + 2 (101)는 :-)하지 (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

파이썬 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 배로 늘리고 첫 번째 숫자를 제거하면 수정해야합니다. m=10**len(x);k=str(randint(m,m*10))[1:];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

@ Leaky Nun 규칙을 조금 변경했습니다.
m654

@ m654 값 사이에 공백이 있다고 어디에서 말했습니까?
Leaky Nun

@LeakyNun 원래 그들에 대한 규칙이 있었지만 제거했습니다.
m654

1
루프를 사용하는 것이 좋습니다. 실제로 여러 입력 버전보다 짧 r거나Yr
Luis Mendo

2

PowerShell v2 +, 79 77 바이트

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

input을 취하고 $n모든 문자를 반복 Random하고 0..9각 반복 에서 요소를 가져 옵니다 . 해당 숫자를 (배열로)에 저장 $x합니다. 해당 배열을 다른 루프로 파이프합니다. 각 반복은 현재 요소를 가져 와서 (암시 적 char-to-int 캐스트)에서 $_슬라이스 된 위치 char에 추가 $n한 다음로 다시 캐스팅합니다 [char]. 파이프 라인에 그대로 둡니다. 그것은 괄호 안에 들어 -join있고 단어를 형성하기 위해 함께 ed입니다. 그것은 파이프 라인에 남아 있습니다. 또한이 수 $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에 대한 두 번째 대답이며 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 바이트 절약
  • static클래스 p에서 제거하여 7 바이트 절약
  • @milk 덕분에 24 바이트 절약

1
속임수는 다른 언어와 비교하지 않는 것입니다.) C # 골프에 정통하지는 않지만 b++<i.Count()세 번째 조항을 비워 둘 수 있습니까? 또한 후행 줄 바꿈이 필요하다고 생각하지 않으므로 마지막 호출 WriteLineWrite대신 될 수 있습니다 .
FryAmTheEggman

또한 C #에 정통하지는 않지만 = r.Next (10)을 d 선언으로 이동하고 쓰기에서 괄호 세트를 저장할 수 있다고 생각합니다. 아니면 무작위로 정수를 반환하지 않으므로 그렇게 할 수 없습니까?
theLambGoat

내가 할 수있을 것 같아, 확인해 보자
Tom Doodler

유형을로 바꿀 수 있습니다 var. 즉 , 몇 바이트를 면도하는 var c=대신 string c=.
우유

결과 Console.ReadLine()를 문자열로 남겨 두지 않겠습니까? i.Length보다 짧으면 i.Count()System.Linq가 필요하지 않습니다. 문자열에는 문자 인덱서가 있습니다. 또한 루프에서 새로운 랜덤 객체를 생성하는 것은 더 적은 바이트 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

05AB1E , 18 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

파이썬 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

이 사이트에 오신 것을 환영합니다!
James

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끝에 추가되며 끝에 인쇄됩니다.


키도 인쇄해야합니다.
Alex Howansky

$s.=$rfor 루프에 2 번째 세미 이후 를 넣을 수 있습니다 . 후행 세미를 덤프 할 수 있기 때문에 바이트를 절약 할 수 있습니다. 그런 다음 루프는 하나의 명령문이므로 래핑 괄호를 잘라서 2 바이트를 더 절약 할 수 있습니다. 그런 다음 끝에 $s따옴표로 묶은 문자열 안에 .연산자를 추가하여 한 바이트 더 저장할 수 있습니다 . :)
Alex Howansky

@AlexHowansky : 사실입니다. 감사
비즈니스 고양이

1

J, 32 바이트

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

파이썬 동등 :

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

펄, 34 바이트

에 +1 포함 -p

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

0

펄, 65 바이트

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

마지막에 줄을 바꾸지 않고 입력을 얻는 방법을 알아 내기 위해 잠시 시간을 들였습니다. 명령 행 인수로 사용


솔루션에 몇 가지 문제가 있습니다. 입력 내용은 STDIN 형식으로 읽히지 $;않고 비어 있지 않으므로 오래된 내용을 인쇄하며 랜드는 9를 생성 할 수 없습니다. 수정하기 쉽고 STDIN을 사용하면 코드가 더 짧아집니다 :-)
Ton Hospel

@TonHospel 일반적으로 입력 요구 사항이 느슨하고 STDIN에 비해 인수가 허용되며 STDIN에서 입력을받는 것이 더 짧은 반면 줄 바꿈을 제거해야 더 길어집니다. 랜드 숫자 생성 않는 반면 <9 펄의 INT 방법 라운드보다는 바닥 그래서 아무것도> = 8.5 9로 끝낼한다
theLambGoat

입력 요구 사항은 일반적으로 느슨하지만 여기서는 그렇지 않았습니다. STDIN에서 개행 문자를 얻는 것은 쉽지 않습니다 : <>=~/./g. 그리고 int펄에서 0을 향해 자르면 둥글 지 않습니다. perl -wle 'print int 8.6'출력8
Ton Hospel

0

파이썬 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은 내가 그것을 어떻게 그리웠는지 모른다. 감사-고정
atlasologist

필자는 이전 버전의 Python 답변과 동일한 문제가 있다고 생각합니다. 선행 0을 가진 키를 생성하지 않습니다.
TheBikingViking

@TheBikingViking 다시 고정
atlasologist

변경 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

Senva , 74 바이트

내가 만든 가장 짧은 프로그램은 다음과 같습니다.

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

약간의 설명? (참고 : BMBack-Memory를 의미합니다 ) :

// === 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 바이트

문자열 매개 변수를 사용하고 두 문자열 (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.