Bu anahtar şifresini uygulayın


13

Bu anahtar şifresini uygulayın

Hedef

Belirli bir şifreyi uygulamak için algoritmayı (Algoritma bölümünde açıklanmıştır) kullanın.

Program, STDIN veya mevcut en yakın eşdeğerden girişi okumalıdır, şifreleme metnini ve bir anahtarı oluşturmak için algoritmayı kullanın.

Şifre metni ve anahtar STDOUT'a veya mevcut en yakın eşdeğere yazılır. Şifreleme metnini ve anahtarı çıktığı sürece herhangi bir biçime izin verilir.

Algoritma

Dizedeki karakterleri ilgili ASCII değerlerine dönüştürün. Örneğin:

Hello -> 72 101 108 108 111

Daha sonra, 0-9 aralığında rastgele sayılar içeren dize sürece bir anahtar oluşturmanız gerekecektir.

Hello -> 62841

Rastgele sayı dizisindeki tam sayıları dizenin ASCII değerlerine ekleyin. Yukarıdaki örneklerde 72, 78 ve 101, 104 olacaktır.

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

Ardından, yeni değerleri tekrar karakterlere dönüştürün. Yukarıdaki örneklerde metin Hellohaline gelmiştir Ngtpp.

Örnekler

(Bunlar basitçe çıktı ne örnekleridir olabilir benziyor. Çıkışı ve değişecektir edebilirsiniz.)

Hello World

Lfrlu)_supg
41606984343

This will be encoded

Zhjs$~koo gj$iuhofgj
60104723305544750226

kurallar

  • Girişin yalnızca az, AZ ve boşluk aralığında karakterler içerdiğini varsayabilirsiniz.
  • Başvurular tam programlar veya işlevler olmalıdır.
  • Gönderiler bayt olarak puanlanacaktır.
  • Standart boşluklar yasaktır.
  • Bu kod golf, bu yüzden en kısa kod kazanır.

(Bu benim ilk zorluklarımdan biri, eğer yanlış bir şey varsa, bana nasıl geliştirebileceğimi söylemekten çekinmeyin.)


5
Bu meydan okuma benim için iyi görünüyor, birkaç düşünce dışında. 1. Tam program yerine bir işleve izin veriliyor mu? İlgili bir soru, değerler yazdırılmak yerine döndürülebilir mi? 2. Dediniz ki preferably with the format (ciphertext)\n(key)."tercih edilen özellikler" ve kod golf çok iyi karıştırmayın. Bunu zorunlu hale getirmeli veya diğer çıktı biçimlerine izin vermelisiniz. 3. Anahtarın boşluk bırakmadan yazdırılması gerekiyor mu? Liste formatında yazdırmaya ne dersiniz [0, 5, 2, ...]?
James

Anahtarın başında sıfır olabilir mi?
TheBikingViking

1
Güzel bir ilk zorluk ama katı IO formatlarından emin değilim. Genellikle fonksiyonlara izin verilir ve genellikle cevaplar kabul edilen ES yöntemlerinden birinden okunabilir. Bu, öğelerle bir dizi çıktısını da içerir
Downgoat

1
Anahtarın rakamları tekdüze bir dağılımla oluşturulmalı mı?
Dennis

1
Uh ... 101 + 2 104 değil,
103'tür.

Yanıtlar:


5

Jöle , 12 9 bayt

⁵ṁX€’Ṅ+OỌ

Çevrimiçi deneyin!

Nasıl çalışır

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

@Rod'a bir hataya işaret ettiği için teşekkürler

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)

Bağımsız değişken aracılığıyla girdi dizesi olarak alan ve STDOUT'a yazdırılan bir işlev.

Nasıl çalışır

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 üzerinde deneyin


anahtar üreteciniz 0 ile başlayan anahtarlar oluşturmaz. sınırları 10 kat arttırmak ve 1. basamağı kaldırmak düzeltilmelidir: m=10**len(x);k=str(randint(m,m*10))[1:];ve hatta işlemde bir bayt
Çubuk

@ Çubuk Hatayı işaret ettiğiniz için teşekkür ederiz. Ancak bu randint, baytları kurtaramaz, çünkü kapsayıcıdır, yani yapmanız gerekir m*10-1. Aynı bayt sayımı için düzeltmenin bir yolunu düşündüm.
TheBikingViking


3

Aslında 17 bayt

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

Çevrimiçi deneyin!

Açıklama:

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

"10r*]v!kGy+c

Çıktı şöyle görünür:

9 5 8 2 1
Qjtnp

Çevrimiçi deneyin!

Açıklama:

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

Bunun doğru format olup olmadığından emin değilim ...
Leaky Nun

@Leaky Nun Kuralları biraz değiştirdim.
m654

@ m654 Değerler arasında boşluklar nerede olabilir dedin?
Leaky Nun

@LeakyNun Başlangıçta onlara karşı bir kural vardı ama kaldırdım.
m654

1
Döngüyü kullanmak için iyi bir fikir. Aslında rya da çok girişli versiyonundan daha kısaYr
Luis Mendo

2

PowerShell v2 +, 79 77 bayt

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

Girdiyi alır $n, her karakterin üzerinden geçer ve her yinelemeden bir Randomöğe alır 0..9. Bu numaraları (dizi olarak) içine kaydeder $x. Bu diziyi başka bir döngüye bağlar. Her yineleme, geçerli öğeyi alır, $_dilimlenmiş konumsal karaktere ekler $n(örtük karakterden-int dökümü), sonra yeniden yayınlar [char]. Boru hattında bırakır. Bu, parens içinde kapsüllenir -joinve kelimeyi oluşturmak için birlikte düzenlenir. Boru hattında kaldı. Ayrıca, sayı $xda olduğu -joinbirbirine ed ve boru hattı üzerinde bıraktı. Bunlar, Write-Outputyürütme sonunda örtük olarak a ile yazdırılır , bu da varsayılan olarak bir satırsonu ile yazdırılmasına neden olur.

Misal

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

2

C #, 252 247 245 232 216 Bayt

Boyutu diğer çözümlere kıyasla oldukça kötü ama yine de ...

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

Bu benim bir codegolf benim ikinci cevap ve ben C # dikkate oldukça acemi ben bu yüzden nasıl daha kısa almak duymak isterim :)

Ungolfed:

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 sayesinde 5 bayt kurtardı
  • @TheLambGoat sayesinde 2 bayt kaydedildi
  • staticP sınıfından çıkararak 7 bayt kaydedildi
  • @Milk sayesinde 24 bayt kaydedildi

1
Hile diğer dillerle karşılaştırmak değildir;) C # golf'te özellikle iyi bilgili değilim, ancak b++<i.Count()üçüncü fıkrayı boş bırakabilir misiniz ? Ayrıca, sondaki bir yeni satıra ihtiyacınız olduğunu sanmıyorum, bu yüzden son çağrı bunun yerine WriteLineolabilir Write.
FryAmTheEggman

Ben de C # usta değilim ama ben = r.Next (10) d deklarasyona taşımak ve yazma parantez bir dizi kaydedebilirsiniz düşünüyorum. Yoksa rastgele bir int döndürmez, bu yüzden bunu yapamazsınız?
theLambGoat

Bunu yapabileceğimi düşünüyorum, kontrol edeyim
Tom Doodler

Türleri ile değiştirebilirsiniz var. ie- birkaç bayt tıraş etmek var c=yerine string c=.
süt

Neden Console.ReadLine()dize olarak sonucunu bırakmıyorsunuz ? i.Lengthdaha kısadır i.Count(), System.Linq. dize bir char dizinleyicisine sahiptir. Ayrıca oluşturarak yeni Rastgele döngü içinde nesneleri daha az bayt: new Random().Next(10).
süt

2

CJam, 11 bayt

Nq{Amr_o+}/

Çevrimiçi deneyin!

Nasıl çalışır

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 bayt

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

açıklama

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

Çevrimiçi deneyin


2

Python 3, 112 bayt

c, şifrelenmiş metni ve anahtarı döndüren bir işlevdir

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

İşte aynı şeyi yapan ve biraz daha okunabilir bir kod

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

Çıktı:

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

Bu siteye hoş geldiniz!
James

1

PHP, 63 86 82 bayt

Düzenleme: anahtarı yazdırmayı unuttum ...

Beni 4 bayt kurtardığı için Alex Howansky'ye teşekkürler.

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

Giriş bir komut satırı bağımsız değişkeni ile verilir. Dizedeki her karakteri alır ve 0-9 arasında ASCII koduna rastgele bir int ekler, sonra kodu ASCII'ye geri dönüştürür. $sSonuna yazdırılan her rastgele sayı eklenir .


Anahtarı da yazdırmanız gerekir.
Alex Howansky

$s.=$rİkinci yarıdan sonra for döngüsüne koyabilirsiniz, bayt tasarrufu yapabilirsiniz, çünkü sondaki yarısını dökebilirsiniz. Ardından, döngünüz yalnızca bir ifade olacaktır, böylece sarma parantezlerini keserek 2 bayt daha tasarruf edebilirsiniz. Daha sonra $s, .operatörü bir bayt daha kaydedecek şekilde alıntılanan dizenin içine koyabilirsiniz . :)
Alex Howansky

@AlexHowansky: Bu çok doğru. Teşekkürler
Business Cat

1

J, 32 bayt

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

python eşdeğeri:

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 bayt

İçin +1 içerir -p

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

0

Perl, 65 bayt

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

Sonunda yeni bir satır olmadan girişi nasıl alacağımı anlamaya çalıştım. Komut satırı argümanı olarak alır


Çözümünüzün bazı sorunları var. Giriş STDIN formundan okunmuyor, $;boş başlamıyor , bu yüzden eski içeriği yazdırıyor ve rand hiçbir zaman 9
üretemiyor

@TonHospel Genellikle giriş gereksinimleri gevşektir ve STDIN üzerinden argümanlar kabul edilebilir ve STDIN'den girdi almak daha kısa olurken, yeni satırı buradan kaldırmak daha uzun sürer. Ve rand <9 rakamı üretirken, Perl'in int yöntemi zemin yerine yuvarlar, bu nedenle = 8.5 olan her şey 9 olarak
bitmelidir

Girdi gereksinimleri genellikle gevşek, ama burada değildi. STDIN'den olmayan yeni satır girmek kolay: <>=~/./g. Ve hayır, intperl 0'a doğru kesilir, yuvarlanmaz. perl -wle 'print int 8.6'çıkışlar8
Ton Hospel

0

Python 2, 84 99 bayt

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()Rasgele sayılar oluşturmak için dizenin değerini kullanır .

Dene


Anahtarın yanı sıra şifre metnini de çıktı olarak almanız gerekir.
TheBikingViking

@TheBikingViking bunu nasıl özlediğimi bilmiyorum. Teşekkürler - sabit
atlasolog

Bunun da Python cevabımın önceki bir versiyonuyla aynı problemi olduğunu düşünüyorum; başlarında sıfır bulunan anahtarlar üretmez.
TheBikingViking

@TheBikingViking Tekrar düzeltildi
atlasologist

değiştirmek map(chr,[ord(a)+int(b)for a,b in zip(x,y)])için map(lambda x,y:chr(ord(x)+int(y)),x,y)? bir şey kurtarmak gerekir
ljeabmreosn

0

Senva , 74 bayt

İşte yaptığım en kısa program:

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

Biraz açıklama mı? (Not: BM , Arka Bellek anlamına gelir ):

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

Bu şimdi daha büyük görünüyor, doğru: p? Belki bu kodu optimize etmek mümkündür, ama şimdilik bulduğum en kısa şey bu.


0

C #, 174 bayt

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

Ungolfed:

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

Gerçekten çok basit.


0

Perl 6: 55 veya 70 bayt

Bir string parametresi alan ve iki dizenin (54 karakter, 55 bayt) bir listesini döndüren anonim bir işlev olarak :

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

STDIN'den okuyan ve STDOUT'a yazan bir program olarak (69 karakter, 70 bayt) :

my @a=get.ords;my @n=^9 .roll(@a);say (@a Z+@n)».chr.join;say @n.join
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.