Bilgisayar Şifresi


14

Giriş:

Bir zamanlar çocukken derlediğim bir belgede saklanan birçok farklı şifrem var, zorluklar için en uygun olduğunu düşündüğüm birkaç tanesini (çok önemsiz ve çok zor değil) seçtim ve onları zorluklara dönüştürdüm. Birçoğu hala sanal alanda ve hepsini mi yoksa sadece birkaçını mı göndereceğimden henüz emin değilim. Ama işte bunlardan ilki olan ilk kişi.


Bir Bilgisayar Şifresi, verilen metni belirli bir 'rastgele' karakter gruplarına şifreleyecektir length. Böyle bir grup bir rakam içeriyorsa, şifrelenmiş karakter için kendi grubunu dizine eklemek için bu rakamı kullanır. Grupta hiçbir rakam yoksa, bu ilk karakterin kullanıldığı anlamına gelir.

Örneğin, metnin this is a computer cipherbelirli bir uzunluğunu şifrelemek istediğimizi varsayalım 5. Bu potansiyel bir çıktıdır (not: sayılar aşağıdaki örnekte 1 dizinlenmiştir):

t     h     i     s     i     s     a     c     o     m     p     u     t     e     r     c     i     p     h     e     r       (without spaces of course, but added as clarification)
qu5dt hprit k3iqb osyw2 jii2o m5uzs akiwb hwpc4 eoo3j muxer z4lpc 4lsuw 2tsmp eirkr r3rsi b5nvc vid2o dmh5p hrptj oeh2l 4ngrv   (without spaces of course, but added as clarification)

Grubun nasıl deşifre edileceğini açıklamak için birkaç grubu örnek olarak ele alalım:

  • qu5dtBu grup, bir basamak içeren 5bu grubun (1-endeksli) 5. karakter şifresi çözülmüş metin için kullanılan bir karakter, yani: t.
  • hprit: Bu gruptaki ilk karakteri şifresi çözülmüş metin için dolaylı kullanılır Bu gruba hiçbir basamak içerir: h.
  • osyw2Bu gruplar, bir basamak içeren 2bu grubun (1-endeksli) 2. karakter şifresi çözülmüş metin için kullanılan bir karakter, yani: s.

Meydan okuma:

Bir tamsayıyı verilen lengthve dize word_to_encipherbir çıkış, rasgele , yukarıda tarif edildiği gibi şifrelenmiş dize.

Yalnızca verilen encipher zorunda lengthve word_to_enciphergerek de bir deşifre programı / fonksiyonu oluşturmak, böylece. Ancak gelecekte deşifre için bir bölüm 2 meydan okuma yapabilir.

Zorluk kuralları:

  • lengthAralıkta olacağını varsayabilirsiniz [3,9].
  • Vasiyetnamenin word_to_enciphersadece harf içerdiğini varsayabilirsiniz .
  • Tam küçük harf veya tam büyük harf kullanabilirsiniz (lütfen yanıtınızda hangisini kullandığınızı belirtin).
  • Çıktılarınız, her grup ve bir gruptaki (varsa) basamakların konumları eşit olarak rastgele olmalıdır . Yani alfabenin tüm rastgele harfleri aynı olma şansına sahiptir; şifrelenmiş mektubun her gruptaki konumu aynı olma şansına sahiptir; ve basamağın konumu aynı olma şansına sahiptir (ilk karakter olduğu ve hiçbir basamağın bulunmadığı durumlar hariç ve açıkça şifrelenmiş karakterle aynı konumda olamaz).
  • Ayrıca, 1 dizinli yerine 0 dizinli rakamlar kullanmanıza izin verilir. Lütfen yanıtınızda kullandığınız ikisinden hangisini kullandığınızı belirtin.
  • Rakam 1(veya 00 dizinli olduğunda) çıkışta hiçbir zaman mevcut olmaz. Yani b1ndhkarakteri 'b' şifrelemek için geçerli bir grup değil. Bununla birlikte, b4tbwburada, geçerlidir 4şifrelemektedir b4. (1-endeksli) konumu ve diğer karakter b, t, w(tesadüfen aynı zamanda içeren rasgele b). Diğer olası geçerli gruplar length: 5 karakteri 'b' olan şifrelemek için abcd2, ab2de, babbk, hue5b, vb

Genel kurallar:

  • Bu , bayt en kısa cevap kazanır.
    Kod golf dillerinin, kod yazmayan dillerle yanıt göndermenizi engellemesine izin vermeyin. 'Herhangi bir' programlama dili için mümkün olduğunca kısa bir cevap bulmaya çalışın.
  • Varsayılan I / O kuralları ile cevabınız için standart kurallar geçerlidir , bu nedenle STDIN / STDOUT, fonksiyonlar / yöntem, uygun parametreler ve dönüş tipi, tam programlar ile kullanılabilir. Çağrınız.
  • Varsayılan Loopholes yasaktır.
  • Mümkünse, lütfen kodunuz için bir test içeren bir bağlantı ekleyin (örn. TIO ).
  • Ayrıca, cevabınız için bir açıklama eklemeniz şiddetle tavsiye edilir.

Test senaryoları:

Input:
 Length:           5
 Word to encipher: thisisacomputercipher
Possible output:
 qu5dthpritk3iqbosyw2jii2om5uzsakiwbhwpc4eoo3jmuxerz4lpc4lsuw2tsmpeirkrr3rsib5nvcvid2odmh5phrptjoeh2l4ngrv

Input:
 Length:           8
 Word to encipher: test
Possible output:
 ewetng4o6smptebyo6ontsrbtxten3qk

Input:
 Length:           3
 Word to encipher: three
Possible output:
 tomv3h2rvege3le

2
"Tek tip" ne anlama geliyor
l4m2

@ l4m2 Herhangi bir çıktı için eşit şansın olduğunu. Yani alfabenin tüm rastgele harfleri aynı olma şansına sahiptir; şifrelenmiş mektubun her gruptaki konumu aynı olma şansına sahiptir; ve basamağın konumu, aynı ilk meydana gelme şansına sahiptir (ilk karakter olduğu ve herhangi bir basamak olmadığı ve aynı zamanda şifrelenmiş karakterle aynı konumda olmadığı hariç).
Kevin Cruijssen

Yani abcd2, ab2de, babbkhepsi aynı? Ayrıca b1akkgeçerli mi?
l4m2

@ l4m2 Evet, her üçü de 'b' karakterini şifreleyen olası çıktılardır. Gelince b1akkhayır derdim. Açıklığa kavuşturmak için meydan açıklamasında düzenleyecektir. İlk karakter şifrelenmişse, hiçbir rakam olmamalıdır.
Kevin Cruijssen

1
Örneğin, length = 3 olduğunda char = "a"; Form "a??"676 olası sonuçları vardır, ama "1a?", "?a1", "2?a", "?2a", only104 sonuçları vardır. Yani, tüm bu 780 sonuçlardan bir sonuç seçmeye çalışıyorsam, "şifrelenmiş mektubun konumu" dağılımı 13: 1: 1, 1: 1: 1 değil. Ve bunu "tekdüze rastgele" nasıl çalıştığını düşünürüm.
tsh

Yanıtlar:


3

Pyth, 22 bayt

smsXWJOQXmOGQJdO-UQJJz

Çevrimiçi deneyin.

Küçük harf ve sıfır indeksleme kullanır.

açıklama

Çok basit algoritma.

                           Implicit: read word in z
                           Implicit: read number in Q
 m                   z     For each char d in z:
      OQ                     Choose a number 0..Q-1
     J                       and call it J.
         m  Q                Make an array of Q
          OG                 random letters.
        X     d              Place d in this string
             J               at position J.
    W                        If J is not 0,
   X                J        place J in this string
               O             at a random position from
                 UQ          0..Q-1
                -  J         except for J.
  s                          Concatenate the letters.
s                          Concatenate the results.

5

Perl 6 , 125 bayt

->\n{*.&{S:g{.}=(65..90)>>.chr.roll(n).join.subst(/./,$/,:th($!=roll 1..n:)).subst(/./,$!,:th($!-1??(^n+1$!).roll!!n+1))}}

Çevrimiçi deneyin!

Büyük harfle girdi ve çıktı alır. Girdi körelmiş gibi alır f(n)(string). 1 endeksleme kullanır.

Açıklama:

->\n{*.&{ ...  }}   # Anonymous code block that takes a number n and returns a function
     S:g{.}=        # That turns each character of the given string into
                          .roll(n)      # Randomly pick n times with replacement
            (65..90)>>.chr              # From the uppercase alphabet
                                  .join # And join
            .subst(                         ) # Then replace
                   /./,  ,:th($!=roll 1..n:)  # A random index (saving the number in $!)
                       $/               # With the original character
            .subst(                )    # Replace again
                   /./,$!,:th( ... )    # The xth character with $!, where x is:
                           $!-1??          # If $! is not 1
                                 (^n+1$!).roll       # A random index that isn't $!
                                               !!n+1  # Else an index out of range

4

Python 2 , 187 177 176 156 154 148 bayt

lambda l,s:''.join([chr(choice(R(65,91))),c,`n`][(j==n)-(j==i)*(n>0)]for c in s for n,i in[sample(R(l),2)]for j in R(l))
from random import*
R=range

Çevrimiçi deneyin!

Büyük harfleri ve 0 dizinli sayıları kullanır.

-3 byte, Kevin Cruijssen sayesinde


KevinCruijssen Teşekkürler :)
TFeld

Ne anlama sample(R(l),2)[::1|-(random()<.5)]geliyor?
l4m2

@ l4m2 2 sayı alır range(l)ve karıştırır. Ama görünüşe göre örnek siparişi garanti etmiyor, bu yüzden gerekli değil :)
TFeld

Parantezleri kaldıramıyor (j==i)*(n>0)musunuz? Çarpma işleminin çıkarma işlemine göre önceliği vardır değil mi?
Kevin Cruijssen

1
@KevinCruijssen Evet, bazı problemlerim olduğunda onları kaldırmayı unuttum
TFeld


3

R , 134 132 123 bayt

function(S,n,s=sample)for(k in utf8ToInt(S)){o=k+!1:n
P=s(n,1)
o[-P]=s(c(P[i<-P>1],s(17:42,n-1-i,T)))+48
cat(intToUtf8(o))}

Çevrimiçi deneyin!

Büyük harf alır.

Eski kodun açıklaması (çoğunlukla aynı yaklaşım):

function(S,n){s=sample				# alias
K=el(strsplit(S,""))				# split to characters
o=1:n						# output array
for(k in K){					# for each character in the string
P=s(n,1)					# pick a Position for that character
o[-P]=						# assign to everywhere besides P:
      s(					# a permutation of:
	c(P[i<-P>1],				# P if it's greater than 1
		s(letters,n-1-i,T)))		# and a random sample, with replacement, of lowercase letters
o[P]=k						# set k to position P
cat(o,sep="")}}					# and print

2

Java (JDK) , 193 bayt

s->n->s.flatMap(c->{int a[]=new int[n],i=n,x=0;for(;i-->0;)a[i]+=Math.random()*26+97;a[i+=Math.random()*n+1]=c;x+=Math.random()*~-n;if(i>0)a[x<i?x:x+1]=48+i;return java.util.Arrays.stream(a);})

Çevrimiçi deneyin!

  • Dizin 0 tabanlıdır.
  • Bu giriş, giriş olarak bir IntStream(geçildi String::chars) yanı sıra bir sayı kullanır ve bir başkasını döndürür IntStream.
  • Dan Casts doubleiçin intçünkü gereksizdir +=hack.

2

Japt , 29 bayt

;£=VöJ;CöV hUÎX hUÅÎUÎ?UÎs:Cö

Çevrimiçi deneyin!

Sıfır endekslendi.

Açıklama:

;                                :Set C = [a...z]
 £                               :For each character of the input:
  =VöJ;                          : Get two different random indexes from [0,length)
       CöV                       : Get 5 random letters
           hUÎX                  : Replace one at random with the character from the input
                hUÅÎ             : Replace a different random character with:
                    UÎ?          :  If the input character was not placed at 0:
                       UÎs       :   The index of the input character
                          :      :  Otherwise:
                           Cö    :   A random letter
                                 :Implicitly join back to a string

2

C, 115 bayt

g(_,n)char*_;{int i=rand(),j=i%~-n,k=0;for(i%=n;k<n;k++)putchar(k-i?!i|i<k^k-j?rand()%26+97:48+i:*_);*++_&&g(_,n);}

Çevrimiçi deneyin!

0 dizinli, küçük harf.

Hafifçe soluksuz ve genişledi:

g(char*_,int n) {
    int i = rand(), j = i%(n-1), k = 0;
    for(i = i%n; k<n; k++)
        putchar(k!=i ? i!=0 || k==j + (k>i)
                          ? rand()%26 + 'A'
                          : i + '0')
                    : *_);
    if (*++_!=0) g(_,n);
}

Kod oldukça basit olmalıdır. Bir çağrıda oluşturulan iki rastgele i, gcd ( , ) = 1 olduğundan bağımsızdır ve büyüktür.jrand()n~-nRAND_MAX


1
PPCG'ye Hoşgeldiniz! :)
Shaggy

1

Temiz , 256 bayt

import StdEnv
s::!Int->Int
s _=code {
ccall time "I:I"
ccall srand "I:I"
}
r::!Int->Int
r _=code {
ccall rand "I:I"
}
$n|s 0<1#k=map\e.r e rem n
=flatten o map\c.hd[map(\i|i==x=c=toChar if(i==y&&x>0)(x+48)(r i rem 26+97))[0..n-1]\\x<-k[0..]&y<-k[0..]|x<>y]

Çevrimiçi deneyin!

Chooses:

  • rastgele x(karakterin segmentteki konumu)
  • yeşit olmayan bir rasgele x(rakamın segmentteki konumu)
  • her konum xiçin , sıfır yolmadığı sürece eşit olmayan, rastgele küçük bir harfx

1

JavaScript, 134 bayt

l=>w=>w.replace(/./g,c=>eval("for(s=c;!s[l-1]||s[t?t-1||9:0]!=c;t=s.replace(/\\D/g,''))s=(p=Math.random()*36**l,p-p%1).toString(36)"))

Çevrimiçi deneyin!

Bu yanıt, tüm olası kodlanmış dizelerden kodlanmış dizeyi eşit olarak seçti. Bu yüzden kodlanmış harfi ilk harf olarak yapmak daha mümkündür.


1

C # (Visual C # Etkileşimli Derleyici) , 171 bayt

s=>n=>{var r=new Random();return s.SelectMany(c=>{int i=r.Next(n),j=r.Next(n-1);j+=j<i?0:1;return new int[n].Select((_,k)=>(char)(i==k?c:j==k&i>0?i+49:r.Next(26)+97));});}

Çevrimiçi deneyin!

Açıklama ...

// s is the input string
// n is the input length
s=>n=>{
  // we need to create an instance
  // of Random and use throughout
  var r=new Random();
  // iterate over s, each iteration
  // returns an array... flatten it
  return s.SelectMany(c=>{
    // i is the position of the letter
    // j is the position of the number
    int i=r.Next(n), j=r.Next(n-1);
    // ensure i and j are different
    j+=j<i?0:1;
    // create an iterable of size n
    return new int[n]
      // iterate over it with index k
      .Select((_,k)=>(char)(
        // return the letter
        i==k?c:
        // return the number
        j==k&i>0?i+49:
        // return a random letter
        r.Next(26)+97)
      );
  });
}

1

Kömür , 35 30 bayt

NθFS«≔‽θη≔∧η‽Φθ⁻κηζFθ≡κζIηηι‽β

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. 0 endeksli. Açıklama:

Nθ

Uzunluğu girin.

FS«

Kelimeyi girin ve karakterlerin üzerine gelin.

≔‽θη

Deşifre edilen harf için rastgele bir konum seçin.

≔∧η‽Φθ⁻κηζ

Harf 0 konumunda olmadığı sürece rakam için farklı bir rastgele konum seçin, bu durumda rakamı 0 konumuna getirin.

Fθ≡κ

Her çıkış karakteri için bir kez döngü yapın ve konumu açın.

ζIη

Rakamın konumu buysa, deşifre edilen harfin konumunu girin.

ηι

Ancak bu, deşifre edilen mektubun konumu ise, mektubu çıktılayın. Birden fazla anahtar kutusu aynı değere sahipse, Kömür son girişi alır çünkü bu rakamın konumundan önceliklidir.

‽β

Aksi takdirde rastgele bir harf çıktısı alın.


0

05AB1E , 26 bayt

ε²Ý¨Ω©A.r²£Šǝ®Āi®²Ý¨®KΩǝ]J

0 endeksli.

Çevrimiçi deneyin veya tüm test senaryolarını doğrulayın .

Açıklama:

ε            # Map over the characters of the first (implicit) input-string:
 ²Ý¨         #  Create a list in the range [0, second input)
    Ω        #  Get a random item from this list
     ©       #  Store it in the register (without popping)
 A           #  Push the lowercase alphabet
  .r         #  Shuffle it
    ²£       #  Leave only the first second input amount of characters
      Š      #  Triple swap, so the stack order becomes:
             #  random index; random string; map-character
       ǝ     #  Insert the map-character at this random index into the random string
 ®Āi         #  If the random index was NOT 0:
    ®        #   Push the random index
    ²Ý¨      #   Push the list in the range [0, second input) again
       ®K    #   Remove the random index from this list
         Ω   #   Get a random item from this list
          ǝ  #   Insert the first random index at the second random index into the string
]            # Close both the if-else and map
 J           # Join all strings together (and output implicitly)
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.