实施此关键密码


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

规则

  • 您可以假定输入将仅包含z,AZ和空格范围内的字符。
  • 提交的内容必须是完整的程序或功能。
  • 提交内容将以字节计分。
  • 禁止出现标准漏洞
  • 这是代码高尔夫球,因此最短的代码获胜。

(这是我的第一个挑战,如果有什么问题,请随时告诉我如何改进它。)


5
除了一些想法,这个挑战对我来说看起来不错。1.是否允许使用功能而不是完整程序?一个相关的问题是可以返回值而不是打印值吗?2.您说preferably with the format (ciphertext)\n(key).“首选功能”和代码高尔夫并不太好。您应该将其设置为强制性或允许其他输出格式。3.密钥必须打印时没有空格吗?以列表格式打印,例如[0, 5, 2, ...]
詹姆斯,

密钥可以有前导零吗?
TheBikingViking

1
很好的第一个挑战,但是我不确定严格的IO格式。通常允许使用功能,并且通常可以从一种可接受的IO方法中读取答案。这包括输出包含以下项的数组
Downgoat '16

1
密钥的数字是否必须均匀分布地生成?
丹尼斯

1
呃... 101 + 2是103,而不是104。:-)
YetiCGN

Answers:


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倍并删除第一个数字应该可以解决: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我稍微修改了规则。
2016年

@ m654您在哪里说这些值之间可以有空格?
Leaky Nun

@LeakyNun最初有一个针对他们的规则,但我删除了它。
m654

1
使用循环的好主意。它实际上比rYr
路易斯·门多

2

PowerShell v2 +,79 77字节

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

获取输入$n,循环遍历每个字符并Random0..9每次迭代中获取一个元素。将这些数字(作为数组)存储到中$x。将该数组传递给另一个循环。每次迭代都采用当前元素$_,将其添加到切出的位置char中$n(隐式char-to-int强制转换),然后重新铸造为[char]。留在管道上。它被封装在括号中并-join一起形成单词。那留在管道上。此外,该数字$x-join一起编辑并保留在管道中。那些Write-Output在执行结束时隐式打印为a ,这导致它们默认情况下以换行符打印。

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

这是我对代码高尔夫的第二次回答,考虑到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#golf,但是您可以b++<i.Count()将第三个子句留空吗?另外,我认为您不需要尾随换行符,因此WriteLine可以直接拨打Write
FryAmTheEggman'8

我也不熟悉C#,但我认为您可以将= r.Next(10)移至d的声明,并在写入时保存一组括号。还是随机变量不返回整数,所以您不能这样做?
theLambGoat '16

我想我可以做到,让我检查一下
Tom Doodler '16

您可以用替换类型var。即,var c=而不是string c=剃一些字节。
牛奶

为什么不将结果保留Console.ReadLine()为字符串?i.Length比短i.Count(),则不需要System.Linq。字符串有一个字符索引器。同样在循环中创建新的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字节

编辑:忘记打印密钥...

感谢Alex Howansky为我节省了4个字节。

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

输入是通过命令行参数给出的。接受字符串中的每个字符,并在其ASCII代码中添加一个0到9之间的随机整数,然后将代码转换回ASCII。每个随机数都附加到$s,并打印在末尾。


您还需要打印密钥。
亚历克斯·霍万斯基

您可以$s.=$r在for循环中将第二个半数后面的内容放进去,从而节省一个字节,因为您可以转储其尾随的半数。然后,您的循环将只有一条语句,因此您可以剪切大括号,从而节省2个字节。然后最后,您可以将带$s引号的字符串放在里面,从而使.运算符再保留一个字节。:)
Alex Howansky '16

@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格式读取的,$;不会以空开头,因此它会打印旧内容,并且rand永远不会生成9。它们很容易修复,使用STDIN会使您的代码更短:-)
Ton Hospel

@TonHospel通常,输入要求比较宽松,并且在STDIN上可以接受args,并且从STDIN接收输入的时间较短,但必须从其中删除换行符,因此会变长。尽管rand的确生成了<9的数字,但Perl的int方法是四舍五入而不是
取整,

输入要求通常是宽松的,但事实并非如此。从STDIN获取非换行符很容易:<>=~/./g。不,int在perl中截断为0时,它不会舍入。perl -wle 'print int 8.6'输出8
Ton Hospel '16

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不知道我是怎么想念的。谢谢–固定
地图集专家,2016年

我认为这也与我的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

Senva,74个字节

这是我制作的最短的程序:

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

一点解释?(注意:BM表示Back-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

现在看起来更大了,是: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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.