Sandi Komputer


14

Pengantar:

Saya memiliki banyak cipher yang berbeda yang disimpan dalam dokumen yang pernah saya kompilasi sebagai seorang anak, saya memilih beberapa yang saya pikir paling cocok untuk tantangan (tidak terlalu sepele, dan tidak terlalu keras) dan mengubahnya menjadi tantangan. Sebagian besar dari mereka masih berada di kotak pasir, dan saya belum yakin apakah saya akan memposting semuanya, atau hanya beberapa. Tapi di sini adalah yang pertama dari mereka untuk memulai.


Computer Cipher akan mengenkripsi teks yang diberikan ke dalam kelompok karakter 'acak' dari suatu yang diberikan length. Jika grup tersebut berisi angka, itu akan menggunakan angka itu untuk mengindeks ke dalam kelompoknya sendiri untuk karakter yang dienkripsi. Jika tidak ada digit yang ada dalam grup, itu berarti karakter pertama digunakan.

Misalnya, katakanlah kita ingin menyandikan teks this is a computer cipherdengan panjang tertentu 5. Ini adalah output potensial (catatan: angka 1-diindeks pada contoh di bawah):

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)

Mari kita ambil beberapa kelompok sebagai contoh untuk menjelaskan cara menguraikan grup:

  • qu5dt: Kelompok ini berisi digit 5, sehingga (1-diindeks) karakter ke-5 dari kelompok ini adalah karakter yang digunakan untuk teks diuraikan: t.
  • hprit: Kelompok ini tidak mengandung angka, sehingga karakter pertama dari kelompok ini digunakan secara implisit untuk teks diuraikan: h.
  • osyw2: Kelompok ini mengandung digit 2, sehingga (1-diindeks) karakter 2 dari kelompok ini adalah karakter yang digunakan untuk teks diuraikan: s.

Tantangan:

Diberikan bilangan bulat lengthdan string word_to_encipher, menghasilkan string acak terenkripsi seperti yang dijelaskan di atas.

Anda hanya perlu mengenkripsikan yang diberikan lengthdan word_to_encipher, jadi tidak perlu membuat program / fungsi penguraikan juga. Saya mungkin membuat tantangan bagian 2 untuk menguraikan di masa depan.

Aturan tantangan:

  • Anda dapat mengasumsikan lengthakan berada dalam kisaran [3,9].
  • Anda dapat mengasumsikan surat word_to_encipherwasiat tersebut hanya berisi surat.
  • Anda dapat menggunakan huruf besar atau huruf besar penuh (sebutkan mana yang Anda gunakan dalam jawaban).
  • Output Anda, setiap grup, dan posisi digit dalam grup (jika ada) harus acak secara seragam . Jadi semua huruf acak dari alfabet memiliki peluang yang sama terjadi; posisi huruf yang dienkripsi dalam setiap kelompok memiliki peluang yang sama terjadi; dan posisi digit memiliki peluang yang sama terjadi (kecuali ketika itu karakter pertama dan tidak ada digit; dan itu jelas tidak bisa berada pada posisi yang sama dengan karakter yang dienkripsi).
  • Anda juga diizinkan untuk menggunakan angka 0-diindeks daripada 1-diindeks. Silakan sebutkan yang mana dari dua yang Anda gunakan dalam jawaban Anda.
  • Digit 1(atau 0ketika 0-diindeks) tidak akan pernah ada dalam output. Jadi b1ndhbukan grup yang valid untuk mengenkripsi karakter 'b'. Namun, b4tbwberlaku, di mana 4enciphers yang bdi-4 (1-diindeks) posisi, dan karakter lain b, t, wadalah acak (yang kebetulan juga berisi b). Kelompok valid kemungkinan lain dari length5 untuk menulis dlm kode karakter 'b' adalah: abcd2, ab2de, babbk, hue5b, dll

Aturan umum:

  • Ini adalah , jadi jawaban tersingkat dalam byte menang.
    Jangan biarkan bahasa kode-golf mencegah Anda memposting jawaban dengan bahasa non-codegolf. Cobalah untuk memberikan jawaban sesingkat mungkin untuk bahasa pemrograman 'apa pun'.
  • Aturan standar berlaku untuk jawaban Anda dengan aturan I / O default , sehingga Anda diizinkan untuk menggunakan STDIN / STDOUT, fungsi / metode dengan parameter yang tepat dan tipe pengembalian, program penuh. Panggilanmu.
  • Celah default tidak diperbolehkan.
  • Jika memungkinkan, silakan tambahkan tautan dengan tes untuk kode Anda (yaitu TIO ).
  • Juga, menambahkan penjelasan untuk jawaban Anda sangat dianjurkan.

Kasus uji:

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
Bagaimana arti "seragam"
l4m2

@ l4m2 Bahwa ada peluang yang sama untuk output apa pun. Jadi semua huruf acak dari alfabet memiliki peluang yang sama terjadi; posisi huruf yang dienkripsi dalam setiap kelompok memiliki peluang yang sama terjadi; dan posisi digit memiliki peluang yang sama terjadi (kecuali ketika itu karakter pertama dan tidak ada digit hadir, dan juga tidak pada posisi yang sama dengan karakter yang dienkripsi).
Kevin Cruijssen

Jadi abcd2, ab2de, babbksemua sama? Juga b1akkvalid?
14m2

@ l4m2 Yap, ketiganya adalah keluaran yang memungkinkan untuk mengenkripsi karakter 'b'. Adapun b1akksaya akan mengatakan tidak. Akan mengeditnya dalam deskripsi tantangan untuk diklarifikasi. Jika karakter pertama adalah karakter terenkripsi, tidak boleh ada digit.
Kevin Cruijssen

1
Misalnya, ketika panjang = 3, char = "a"; Bentuknya "a??"memiliki 676 hasil yang mungkin, tapi "1a?", "?a1", "2?a", "?2a", memiliki only104 hasil. Jadi, jika saya mencoba untuk memilih satu hasil dari semua 780 hasil ini, distribusi "posisi huruf yang dienkripsi" adalah 13: 1: 1, bukan 1: 1: 1. Dan saya akan menganggap ini sebagai cara "acak seragam" bekerja.
tsh

Jawaban:


3

Pyth, 22 byte

smsXWJOQXmOGQJdO-UQJJz

Cobalah online.

Gunakan huruf kecil dan pengindeksan nol.

Penjelasan

Algoritma yang sangat mudah.

                           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 byte

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

Cobalah online!

Membawa input dan output dalam huruf besar. Membawa input yang kari, seperti f(n)(string). Gunakan 1 pengindeksan.

Penjelasan:

->\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 byte

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

Cobalah online!

Menggunakan huruf besar, dan angka 0-diindeks.

-3 byte, terima kasih kepada Kevin Cruijssen


@KevinCruijssen Terima kasih :)
TFeld

Apa sample(R(l),2)[::1|-(random()<.5)]artinya
14m2

@ 14m2 Dibutuhkan 2 angka dari range(l), dan mengocoknya. Tapi ternyata sampel tidak menjamin pesanan, jadi tidak diperlukan :)
TFeld

Tidak bisakah Anda menghapus tanda kurung di sekitar (j==i)*(n>0)? Multiply memiliki operator diutamakan atas pengurangan bukan?
Kevin Cruijssen

1
@KevinCruijssen Ya, saya lupa menghapusnya, ketika saya punya masalah
TFeld


3

R , 134 132 123 byte

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

Cobalah online!

Mengambil huruf besar.

Penjelasan kode lama (sebagian besar pendekatan yang sama):

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 byte

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

Cobalah online!

  • Indeks ini berbasis 0.
  • Entri ini menggunakan IntStream(didapat String::chars) sebagai input, serta nomor dan mengembalikan yang lainIntStream .
  • Pemain dari doubleke inttidak perlu karena +=peretasan.

2

Japt , 29 byte

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

Cobalah online!

Diindeks nol.

Penjelasan:

;                                :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 byte

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

Cobalah online!

Diindeks, huruf kecil.

Sedikit tidak berbulu dan meluas:

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

Kode harus cukup mudah. Dua random i, yang jdihasilkan dalam satu rand()panggilan bagus dan independen karena gcd ( n, ~-n) = 1 dan RAND_MAXbesar.


1
Selamat datang di PPCG! :)
Shaggy

1

Bersih , 256 byte

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]

Cobalah online!

Memilih:

  • acak x(posisi karakter di segmen)
  • acak yyang tidak sama denganx (posisi digit di segmen)
  • huruf kecil acak untuk setiap posisi tidak sama dengan xdan tidak sama dengan ykecuali xnol

1

JavaScript, 134 byte

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

Cobalah online!

Jawaban ini memilih string yang disandikan dari semua string yang mungkin disandikan secara seragam. Jadi lebih mungkin untuk membuat surat yang disandikan sebagai yang pertama.


1

C # (Visual C # Interactive Compiler) , 171 byte

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

Cobalah online!

Penjelasan...

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

Arang , 35 30 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Diindeks 0. Penjelasan:

Nθ

Masukkan panjangnya.

FS«

Masukkan kata dan loop di atas karakter.

≔‽θη

Pilih posisi acak untuk huruf yang diuraikan.

≔∧η‽Φθ⁻κηζ

Pilih posisi acak yang berbeda untuk digit, kecuali jika hurufnya ada di posisi 0, dalam hal ini letakkan digit pada posisi 0 juga.

Fθ≡κ

Ulangi satu kali untuk setiap karakter keluaran dan aktifkan posisi.

ζIη

Jika ini adalah posisi digit maka keluarkan posisi huruf yang diuraikan.

ηι

Tetapi jika ini adalah posisi huruf yang diuraikan maka output surat itu. Ini lebih diutamakan daripada posisi digit karena Charcoal mengambil entri terakhir jika beberapa sakelar saklar memiliki nilai yang sama.

‽β

Kalau tidak, output surat acak.


0

05AB1E , 26 byte

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

Diindeks 0.

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

ε            # 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)
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.