Computer Cipher


14

Introduzione:

Ho un sacco di cifre diverse memorizzate in un documento che una volta ho compilato da bambino, ne ho scelte alcune che pensavo fossero le più adatte alle sfide (non troppo banali e non troppo difficili) e le trasformavo in sfide. Molti di loro sono ancora nella sandbox, e non sono ancora sicuro se li posterò tutti o solo alcuni. Ma qui è il primo di cui iniziare.


Un cifrario informatico codificherà il testo dato in gruppi di caratteri "casuali" di un dato length. Se un tale gruppo contiene una cifra, utilizzerà quella cifra per indicizzarsi nel proprio gruppo per il carattere codificato. Se nessuna cifra è presente nel gruppo, significa che viene utilizzato il primo carattere.

Ad esempio, supponiamo di voler crittografare il testo this is a computer ciphercon una determinata lunghezza di 5. Questo è un potenziale output (nota: i numeri sono 1 indicizzati nell'esempio seguente):

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)

Prendiamo alcuni gruppi come esempi per spiegare come decifrare il gruppo:

  • qu5dt: Questo gruppo contiene una cifra 5, quindi la (1-indicizzato) 5th carattere di questo gruppo è il carattere utilizzato per il testo decifrato: t.
  • hprit: Questo gruppo non contiene cifre, in modo che il primo carattere di questo gruppo viene utilizzato in modo implicito per il testo decifrato: h.
  • osyw2: Questo gruppo contiene una cifra 2, in modo che il (1-indicizzato) 2 ° carattere di questo gruppo è il carattere utilizzato per il testo decifrato: s.

Sfida:

Dato un numero intero lengthe una stringa word_to_encipher, genera una stringa codificata casuale come descritto sopra.

Devi solo crittografare dato il lengthe word_to_encipher, quindi non è necessario creare anche un programma / funzione di decifrazione. Potrei comunque fare una sfida nella seconda parte per la decifrazione in futuro.

Regole della sfida:

  • Puoi presumere che lengthsarà nell'intervallo [3,9].
  • Puoi presumere word_to_encipherche conterrà solo lettere.
  • È possibile utilizzare lettere maiuscole o minuscole (indicare quale è stato utilizzato nella risposta).
  • Le uscite, ogni gruppo e le posizioni delle cifre in un gruppo (se presente) devono essere uniformemente casuali . Quindi tutte le lettere casuali dell'alfabeto hanno le stesse possibilità di verificarsi; la posizione della lettera codificata in ciascun gruppo ha le stesse possibilità di verificarsi; e la posizione della cifra ha le stesse possibilità di verificarsi (tranne quando è il primo carattere e nessuna cifra è presente; e ovviamente non può trovarsi nella stessa posizione del carattere codificato).
  • È inoltre consentito utilizzare cifre indicizzate 0 anziché 1 indicizzate. Indica quale dei due hai utilizzato nella tua risposta.
  • La cifra 1(o 0quando 0-indicizzata) non sarà mai presente nell'output. Quindi b1ndhnon è un gruppo valido per codificare il carattere 'b'. Tuttavia, b4tbwè valido, dove i 4codificherà i balla 4a posizione (1-indicizzato), e gli altri caratteri b, t, wsono casuali (che contiene anche una coincidenza b). Altri possibili gruppi validi di length5 per cifrare il carattere 'b' sono: abcd2, ab2de, babbk, hue5b, etc.

Regole generali:

  • Questo è , quindi vince la risposta più breve in byte.
    Non lasciare che le lingue di code-golf ti scoraggino dal pubblicare risposte con lingue non codegolfing. Prova a trovare una risposta il più breve possibile per "qualsiasi" linguaggio di programmazione.
  • Le regole standard si applicano alla tua risposta con le regole I / O predefinite , quindi puoi utilizzare STDIN / STDOUT, funzioni / metodo con i parametri corretti e tipo di ritorno, programmi completi. La tua chiamata.
  • Le scappatoie predefinite sono vietate.
  • Se possibile, aggiungi un link con un test per il tuo codice (ad es. TIO ).
  • Inoltre, si consiglia vivamente di aggiungere una spiegazione per la risposta.

Casi test:

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
Cosa

@ l4m2 Che ci sono pari possibilità per qualsiasi output. Quindi tutte le lettere casuali dell'alfabeto hanno le stesse possibilità di verificarsi; la posizione della lettera codificata in ciascun gruppo ha le stesse possibilità di verificarsi; e la posizione della cifra ha la stessa possibilità di verificarsi (tranne quando è il primo carattere e nessuna cifra è presente, e anche non nella stessa posizione del carattere codificato).
Kevin Cruijssen,

Quindi abcd2, ab2de, babbktutti uguali? È anche b1akkvalido?
l4m2

@ l4m2 Sì, tutte e tre le possibili uscite codificano il carattere "b". Quanto a b1akkdirei di no. Lo modificherà nella descrizione della sfida per chiarire. Se il primo carattere è quello crittografato, non dovrebbe essere presente alcuna cifra.
Kevin Cruijssen,

1
Ad esempio, quando length = 3, char = "a"; La forma "a??"ha 676 possibili risultati, ma "1a?", "?a1", "2?a", "?2a", ha only104 risultati. Quindi, se sto provando a scegliere un risultato tra tutti questi 780 risultati, la distribuzione di "posizione della lettera codificata" è 13: 1: 1, non 1: 1: 1. E lo considero come un lavoro "uniformemente casuale".
TSH

Risposte:


3

Pyth, 22 byte

smsXWJOQXmOGQJdO-UQJJz

Provalo online.

Utilizza lettere minuscole e indicizzazione zero.

Spiegazione

Algoritmo molto semplice.

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

Provalo online!

Accetta input e output in maiuscolo. Accetta input al curry, come f(n)(string). Utilizza 1 indicizzazione.

Spiegazione:

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

Provalo online!

Utilizza lettere maiuscole e numeri con indice 0.

-3 byte, grazie a Kevin Cruijssen


@KevinCruijssen Grazie :)
TFeld

Cosa sample(R(l),2)[::1|-(random()<.5)]significa?
l4m2

@ l4m2 Prende 2 numeri range(l)e li mescola. Ma a quanto pare il campione non garantisce l'ordine, quindi non è necessario :)
TFeld

Non riesci a rimuovere la parentesi (j==i)*(n>0)? La moltiplicazione ha la precedenza dell'operatore sulla sottrazione, no?
Kevin Cruijssen,

1
@KevinCruijssen Sì, ho dimenticato di rimuoverli, quando ho avuto dei problemi
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))}

Provalo online!

Accetta lettere maiuscole.

Spiegazione del vecchio codice (principalmente lo stesso approccio):

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

Provalo online!

  • Gli indici sono basati su 0.
  • Questa voce utilizza un IntStream(ottenuto String::chars) come input, nonché un numero e ne restituisce un altroIntStream .
  • I cast da doublea intnon sono necessari a causa +=dell'hacking.

2

Japt , 29 byte

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

Provalo online!

Zero indicizzati.

Spiegazione:

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

Provalo online!

0 indicizzato, minuscolo.

Leggermente ungolfed ed espanso:

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

Il codice dovrebbe essere piuttosto semplice. I due randoms i, jgenerati in una rand()chiamata sono buoni come indipendenti poiché gcd ( n, ~-n) = 1 ed RAND_MAXè grande.


1
Benvenuti in PPCG! :)
Shaggy,

1

Pulito , 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]

Provalo online!

sceglie:

  • una casuale x(posizione del personaggio nel segmento)
  • un casuale yche non è uguale a x(posizione della cifra nel segmento)
  • una lettera minuscola casuale per ogni posizione non uguale a xe non uguale a ymeno che xsia zero

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

Provalo online!

Questa risposta ha scelto la stringa codificata da tutte le possibili stringhe codificate in modo uniforme. Quindi è più possibile rendere la lettera codificata come la prima.


1

C # (compilatore interattivo Visual C #) , 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));});}

Provalo online!

Spiegazione...

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

Carbone di legna , 35 30 byte

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

Provalo online!Il collegamento è alla versione dettagliata del codice. 0-indicizzati. Spiegazione:

Nθ

Inserisci la lunghezza.

FS«

Inserisci la parola e passa sopra i caratteri.

≔‽θη

Scegli una posizione casuale per la lettera decifrata.

≔∧η‽Φθ⁻κηζ

Scegli una posizione casuale diversa per la cifra, a meno che la lettera non sia nella posizione 0, nel qual caso metti anche la cifra nella posizione 0.

Fθ≡κ

Ripeti una volta per ogni carattere di output e attiva la posizione.

ζIη

Se questa è la posizione della cifra, quindi emettere la posizione della lettera decifrata.

ηι

Ma se questa è la posizione della lettera decifrata, quindi emettere la lettera. Ciò ha la precedenza sulla posizione della cifra perché Charcoal prende l'ultima voce se più casi di commutazione hanno lo stesso valore.

‽β

Altrimenti emetti una lettera casuale.


0

05AB1E , 26 byte

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

0-indicizzati.

Provalo online o verifica tutti i casi di test .

Spiegazione:

ε            # 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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.