Escribir un codificador de cifrado VIC

18

El cifrado VIC es uno de los cifrados de lápiz y papel más complicados jamás diseñados. Utilizado en la década de 1950 por el espía soviético Reino Häyhänen, con el nombre en código "VICTOR", su principio principal es la seguridad a través de la ofuscación; una gran cantidad de ofuscación.

Su tarea es escribir un programa o función que tome un mensaje y lo codifique utilizando el cifrado VIC. También he publicado un desafío de decodificador de cifrado VIC aquí . Si alguna de las siguientes instrucciones no es clara, no dude en preguntar sobre ellas en los comentarios. Las instrucciones están adaptadas de este sitio .

Codificación del cifrado VIC

Preparación

Necesitará cinco entradas:

  • el mensaje de texto sin formato
  • una palabra clave o frase corta que contiene las letras más comunes en su idioma
  • una frase clave, como una cita o una línea de una canción (al menos 20 caracteres)
  • una fecha (u otro número de seis dígitos o más)
  • un número de agente personal

En la práctica, estos últimos cuatro deben ser acordados previamente por el remitente y el destinatario, incluido si el número de agente del remitente o el destinatario se utiliza en la codificación.

Mi mensaje de ejemplo será: We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot 3.

Estaremos codificando en inglés (aunque puede usar cualquier idioma y alfabeto que prefiera) y las letras más comunes en el alfabeto inglés son A, E, I, N, O, R, S, T. Usaré la palabra clave SENATORI.

Mi frase clave es una cita de Richard Feynman: "El primer principio es que no debes engañarte a ti mismo, y eres la persona más fácil de engañar".

Como fecha, usaré el 31 de julio de 2016 (en el formato 3172016), que es el día en que escribí esta descripción.

El número personal que he elegido para mí es 9.

Resumen de pasos

  1. Derive las claves intermedias para usar en los siguientes pasos.
  2. Construye y aplica el tablero de damas a caballo.
  3. Construya y aplique la primera tabla de transposición.
  4. Construya y aplique la segunda tabla de transposición (interrumpida).
  5. Finalice el mensaje insertando el grupo indicador de mensaje.

Submecanismos

Dos cosas más que explicar antes de entrar en el meollo del asunto: los procesos de adición de cadena y secuenciación.

La adición de cadena, también conocida como un generador de Fibonacci rezagado, funciona tomando una secuencia de dígitos inicial, agregando los primeros dos dígitos sin llevarlos (agréguelos juntos luego mod 10) y agregando el resultado al final. Por ejemplo:

79081
7 + 9 = 6

790816
9 + 0 = 9

7908169
0 + 8 = 8

79081698
8 + 1 = 9

790816989
1 + 6 = 7

7908169897
... and so on

La secuenciación es esencialmente tomar una secuencia de letras o dígitos y etiquetarlos por su orden alfabético / numérico. Los duplicados se etiquetan de izquierda a derecha. Por ejemplo:

E X A M P L E
    0           # A
1   0       2   # Es
1   0     3 2   # L
1   0 4   3 2   # M
1   0 4 5 3 2   # P
1 6 0 4 5 3 2   # X

3  3  0  5  8  4  2  0  4  7  5  4  8  1
      0              1                     # 0s
      0              1                 2   # 1
      0           3  1                 2   # 2
4  5  0           3  1                 2   # 3s
4  5  0        6  3  1  7        8     2   # 4s
4  5  0  9     6  3  1  7    10  8     2   # 5s
4  5  0  9     6  3  1  7 11 10  8     2   # 7
4  5  0  9 12  6  3  1  7 11 10  8 13  2   # 8s

Aquí uso la indexación cero, pero indexe como quiera.

1. Claves intermedias

Divida las primeras 20 letras de la frase clave en dos grupos de 10 y secuencialice cada uno individualmente, lo que llamaremos S1y S2.

    THEFIRSTPR
S1: 8201357946

    INCIPLEIST
S2: 2603751489

Elija un identificador de mensaje aleatorio de 5 dígitos M(esta puede ser una de las entradas si lo prefiere):

M = 47921

Reste, sin pedir prestado (restar mod 10), los primeros cinco dígitos de la fecha clave 3172016de M:

M      47921
date - 31720
     = 16201

Cadena agregue el resultado hasta que tenga diez dígitos:

1620178218

Agregue estos dígitos a S1, sin llevar o mod 10, para obtener G:

     1620178218
S1 + 8201357946
G  = 9821425154

Arriba S2, escriba la secuencia 0123456789. Localice cada dígito de Gen la secuencia 0123456789 y reemplácelo con el dígito directamente debajo de él S2. El resultado es T.

   0123456789
S2 2603751489

G  9821425154
T  9806705657

Use la adición de cadena para expandir Ta 60 dígitos.

9806705657

becomes

980670565778637511245490262369939288595822106344304316978734

Estos últimos 50 dígitos, en cinco filas de diez dígitos cada uno, forman el Ubloque.

T  9806705657
U  7863751124
   5490262369
   9392885958
   2210634430
   4316978734

Los dos últimos dígitos no iguales del Ubloque se agregan individualmente al número personal del agente para dar el ancho de las dos transposiciones, py q.

9 + 3 = 12 (p, primer ancho de transposición) 9 + 4 = 13 (q, segundo ancho de transposición)

Secuencializar Ty utilizar esta secuencia para copiar fuera de las columnas del Ubloque, de arriba a abajo, en una nueva fila de dígitos, V.

T     9806705657
seqT  9804612537

U     7863751124
      5490262369
      9392885958
      2210634430
      4316978734

V     69911 56837 12548 26533 30206 13947 72869 49804 84323 75924

Secuencialice los primeros pdígitos para obtener la clave para la primera transposición K1, y los siguientes qdígitos para la clave para la segunda K2.

First 12  6  9  9  1  1  5  6  8  3  7  1  2
K1        6 10 11  0  1  5  7  9  4  8  2  3

Next 13   5  4  8  2  6  5  3  3  3  0  2  0  6
K2        8  7 12  2 10  9  4  5  6  0  3  1 11

Finalmente, secuencialice la fila final del Ubloque para obtener Clos encabezados de columna para el tablero de damas:

U5  4316978734
C   3105968724

2. Tablero de damas a caballo

Primero, daré mi ejemplo de tablero de ajedrez y luego explicaré los principios para crearlo de esa manera:

  3 1 0 5 9 6 8 7 2 4
  S E N A T O R I
2 B D G J L P U W Y .
4 C F H K M Q V X Z #

La primera línea de letras es nuestra palabra clave corta SENATORI. Su palabra clave puede ser cualquier cadena sin duplicados, pero dado que define la fila superior de su tablero de ajedrez, elija sabiamente. Encima de la palabra clave está C, y las otras filas son el resto del alfabeto en el orden que elija. En mi caso, llené el tablero con el resto del alfabeto latino, un signo de puntuación .y una marca para demarcar números #. Esencialmente, el tablero de ajedrez es un cifrado de sustitución elegante. Por ejemplo, "E" se sustituirá con 1, y "W" se sustituirá con 27.

Una vez que hemos codificado nuestro mensaje de texto sin formato con este tablero de ajedrez, pero primero, debemos hacer que el comienzo de nuestro mensaje sea menos obvio dividiéndolo en una posición aleatoria y haciéndolo todo en mayúscula. Para denotar el otro comienzo original, usamos dos puntos completos..

We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot 3.

se convierte

HING ELSE. MOVE TO SAFEHOUSE FOXTROT#3#.. WE ARE
DISCOVERED. TAKE WHAT YOU CAN. BURN EVERYT

Codificamos con el tablero de ajedrez, dándonos:

407020 1293124 496481 96 354114062831 416479869443442424 271 581 
2173436481812124 95451 274059 22628 435024 232880 14818229

Si la longitud del mensaje no es divisible por 5, agregamos algunos caracteres nulos para rellenar el mensaje. Nuestro mensaje tiene 109 dígitos, así que agregaré un nulo: "4".

40702 01293 12449 64819 63541 14062 83141 64798 69443 44242 42715
81217 34364 81812 12495 45127 40592 26284 35024 23288 01481 82294

Nota: Dado que mi mensaje de ejemplo no contiene números, diré aquí que puede designar, digamos, como #3#, que está codificado como 44344aquí.

3. Primera transposición

Cree la tabla de transposición escribiendo K1(desde la sección Claves intermedias) seguido del mensaje codificado del paso anterior, en filas de la misma longitud, debajo de la clave:

K1   6 10 11  0  1  5  7  9  4  8  2  3

     4  0  7  0  2  0  1  2  9  3  1  2
     4  4  9  6  4  8  1  9  6  3  5  4
     1  1  4  0  6  2  8  3  1  4  1  6
     4  7  9  8  6  9  4  4  3  4  4  2
     4  2  4  2  7  1  5  8  1  2  1  7
     3  4  3  6  4  8  1  8  1  2  1  2
     4  9  5  4  5  1  2  7  4  0  5  9
     2  2  6  2  8  4  3  5  0  2  4  2
     3  2  8  8  0  1  4  8  1  8  2  2
     9  4

Tomando las columnas numeradas en orden de sus números obtenemos:

060826428  246674580  151411542  246272922  961311401  082918141
4414434239 118451234  334422028  293488758  0417249224 794943568

4. Segunda transposición

La primera transposición fue relativamente simple. Éste, sin embargo, es una transposición interrumpida. El patrón de interrupción está determinado por el ancho de la tabla y la clave. En nuestro ejemplo, tenemos 110 dígitos y 13 columnas, lo que significa que tendremos 8 filas completas y 6 sobras. Comenzamos a completar la primera fila, pero nos detenemos en la columna 0 y continuamos de la siguiente manera:

K2   8  7 12  2 10  9  4  5  6  0  3  1 11

     0  6  0  8  2  6  4  2  8              stop at 0
     2  4  6  6  7  4  5  8  0  1           continue in a triangle pattern
     5  1  4  1  1  5  4  2  2  4  6
     2  7  2  9  2  2  9  6  1  3  1  1
     4  0  1  0  8  2  9  1  8  1  4  1  4  until the end
     4  1  4  4  3  4  2  3  9  1  1        restart and stop at 1
     8  4  5  1  2  3  4  3  3  4  4  2
     2  0  2  8  2  9  3  4  8  8  7  5  8
     0  4  1                                restart and stop at 2

Luego llenamos los últimos espacios con los dígitos restantes.

K2   8  7 12  2 10  9  4  5  6  0  3  1 11

     0  6  0  8  2  6  4  2  8  7  2  4  9
     2  4  6  6  7  4  5  8  0  1  2  2  4
     5  1  4  1  1  5  4  2  2  4  6  7  9
     2  7  2  9  2  2  9  6  1  3  1  1  4
     4  0  1  0  8  2  9  1  8  1  4  1  4
     4  1  4  4  3  4  2  3  9  1  1  9  4
     8  4  5  1  2  3  4  3  3  4  4  2  3
     2  0  2  8  2  9  3  4  8  8  7  5  8
     0  4  1  5  6  8

Ahora, leemos las columnas exactamente de la misma manera que lo hicimos en la primera transposición.

71431148  42711925  861904185 22614147  45499243  28261334  80218938
641701404 025244820 645224398 271283226 94944438  064214521

Y divide todo en grupos de 5 dígitos:

71431 14842 71192 58619 04185 22614 14745 49924 32826 13348 02189
38641 70140 40252 44820 64522 43982 71283 22694 94443 80642 14521

5. Finalice el mensaje

El paso final es insertar nuestro identificador de mensaje aleatorio 47921, en el mensaje mismo. El último dígito de la fecha clave 6indica la distancia que debe estar el grupo desde el final.

71431 14842 71192 58619 04185 22614 14745 49924 32826 13348 02189 38641
70140 40252 44820 64522 43982 47921 71283 22694 94443 80642 14521

Notas para este desafío

  • Se le dan un mínimo de cinco entradas: el mensaje, la palabra clave de la letra, la frase clave, la fecha y un número personal. Puede incluir dos entradas adicionales: el identificador de mensaje aleatorio y los valores nulos necesarios para rellenar el mensaje, o su función puede generar algunos números aleatorios por sí solo.
  • Puede suponer que todas las entradas son válidas, con el número correcto de dígitos y letras (identificador de mensaje de 5 dígitos, al menos 20 dígitos para la frase clave, y así sucesivamente). Puede suponer que a sus cadenas (el mensaje y las palabras clave) ya se les han eliminado todos los signos de puntuación y espacios, excepto los que permite en su versión, y que los números ya están demarcados con signos numéricos.
  • La primera palabra clave no debe tener letras duplicadas, y en su código, puede suponer que nunca tiene letras duplicadas.
  • El idioma que usa para codificar no importa, siempre y cuando el idioma sea preexistente, el alfabeto sea preexistente y usted especifique qué idioma usará en su respuesta.
  • Cualquiera que sea el alfabeto que emplee para su tablero de damas, puede agregar o quitar símbolos para rellenar el tablero de ajedrez. Especifique para qué utiliza esos símbolos (por ejemplo, puntuación, un símbolo separado de "mensaje de inicio", símbolos para palabras comunes). Puede renunciar por completo al signo de número y deletrear los números o incluir cada dígito en el tablero de ajedrez, usando la ranura donde el signo de número era para otra cosa. Especifique qué tablero de ajedrez utilizó en su respuesta.
  • La salida debe ser una cadena de grupos de cinco dígitos separados por espacios, una lista de enteros de cinco dígitos o algo similar.
  • Usé indexación cero y 0123456789en mi ejemplo. Puede usar 1-indexing y 1234567890, o algún otro sistema en su respuesta, siempre que especifique lo que usó.

Aquí hay un ejemplo de implementación en Ideone .

Esta es una publicación larga y escribí la mayor parte a mano, por lo que si hay alguna parte confusa en esta publicación o errores en mi conteo y transposición, hágamelo saber. ¡Buena suerte y buen golf!

Sherlock9
fuente
1
adding the first two digits without adding¿Te refieres a llevar?
isaacg
@isaacg Sí, lo hice. Editado
Sherlock9
¿Podría aclarar qué quiere decir con without borrowingy without carrying? ¿Te refieres a sumar y restar mod 10, es decir (6+7) mod 10 = 3y (6-8) mod 10 = 8?
R. Kap
@ R.Kap Sí, déjame aclarar eso.
Sherlock9
Es lo que tenemos que demarcan los números?
R. Kap

Respuestas:

10

Python 3 , 1423 1348 1324 1316 1300 1286 1250 1249 1209 1206 1204 bytes

Este es definitivamente el golf más largo que he hecho, y el único golf en el que estaba muy preocupado por quedarme sin nombres de variables de un carácter. Sugerencias de golf bienvenidas. Pruébalo en línea!

Estoy codificando con el alfabeto latino en mayúsculas con caracteres adicionales .y #, usando la indexación 0 y 0123456789al convertir ga t. Mi tablero de damas está en un formato similar al siguiente ejemplo:

  2 9 7 4 5 8 3 1 0 6    # C
  S E N A T O R I        # keyword
0 B D G J L P U W Y .    # remaining alphabet arranged in columns
6 C F H K M Q V X Z #    # . and # at the end

Editar: -63 bytes gracias a la sugerencia de TuukkaX de acortar algunas de las funciones de uso frecuente con variables de una letra. -12 bytes de hacer a, g, tmás compacto.

Editar: -24 bytes de creación eliminando nombres de variables para claves intermedias que solo se usan una vez, a saber a, g, s, S, k, K.

Editar: -74 bytes desde la consolidación H(), T() and C().

Editar: -1 byte gracias a Nick A por su sugerencia de cambiar ord(s[i])+ord(s[i+1])a sum(map(ord,s[i:i+2])). -2 bytes de cambiar 2 +=[a]llamadas a +=a,. -13 bytes de cambiar cómo se G()encuentra el índice del mínimo de s. -2 bytes de cambiar y=(y+1)%va y=-~y%v. -15 bytes desde la asignación k.index()a K. -4 bytes desde la asignación 10a W. -5 bytes desde la asignación 1-I(d[-1])al Xinterior V. -3 bytes de reescritura C()del bucle principal. -2 bytes de reorganización T().

I=int;L=list;E=len;R=range;B=str;J=''.join;W=10
def H(s,e):
 for i in R(e-E(s)):s+=chr(48+sum(map(ord,s[i:i+2]))%32%W)
 return s
def Q(s):
 r=[0]*E(s);s=L(s)
 for z in R(E(s)):b=s.index(min(s));r[b]=z;s[b]="~"
 return r
def T(x,k,d=0):
 u=E(x);v=E(k);g=R(v);K=k.index;n=u//v+1;w=[];e=r=y=0;i=K(y);c=[]
 if d:
  while r<n:
   if r>n-1:i=min(i,(u%v or v))
   w+=L(x[e:e+i]),;e+=i;i+=1;r+=1
   if i>v:y=-~y%v;i=K(y)
  r=y=0;i=v-K(y)
  while r<n:
   w[r]+=L(x[e:e+i]);e+=i;i-=1;r+=1
   if i<1:y+=1;i+=v-K(y);r+=1
  w[-1]+=['']*(v-E(w[-1]))
  for j in g:c+=J(z[j]for z in w),
 else:c=[x[i::v]for i in g]
 s=[0]*v
 for f in g:s[k[f]]=c[f]
 return J(s)
def C(m,s,w,n):
 t={".":s[-2:],"#":s[-1]*2};j=z=0
 for x in R(26):
  v=chr(x+65)
  if v in w:t[v]=s[w.index(v)]
  else:t[v]=s[z-2]+s[j];j+=z;z=-~z%2
 r=J(i.isdigit()and i or t[i]for i in m)
 return r+n[:-E(r)%5]
def V(m,w,P,d,A,M,n):X=1-I(d[-1]);t=J(B(Q(P[W:20])[I(J(B((I(H(J(B((I(M[i])-I(d[i]))%W)for i in R(5)),W)[i])+I(Q(P[:W])[i]))%W)for i in R(W))[i])])for i in R(W));u=H(t,60)[W:];p=A+I(u[-2]);v=T(u,Q(t));z=T(T(C(m,J(B(i)for i in Q(u[40:])),w,n),Q(v[:p])),Q(v[p:p+A+I(u[-1])]),1);e=[z[5*i:5*-~i]for i in R(-(-E(z)//5))];return' '.join(e[:X]+[M]+e[X:])

No golfista:

def chain_add(seq, end):
    for i in range(end - len(seq)):
        seq += chr(48+sum(map(ord,seq[i:i+2]))%32%10)
    return seq

def sequent(seq):
    res = [0]*len(seq)
    seq = list(seq)
    for z in range(len(seq)):
        b = seq.index(min(seq))
        res[b] = z
        seq[b] = "~"
    return res

def transpose(text, keys, disrupt=False):
    if disrupt:
        num_rows = len(text) // len(keys) + 1
        len_last = len(text) % len(keys)
        if len_last == 0:
            len_last = len(keys)
        d_rows = []
        text_index = 0
        current_row = 0
        stop_key = 0
        stop_index = keys.index(stop_key)
        while current_row < num_rows:
            if current_row > num_rows-1:
                stop_index = min(stop_index, len_last)
            d_rows += [list(text[text_index:text_index+stop_index])]
            text_index += stop_index
            stop_index += 1
            if stop_index>len(keys):
                stop_key = (stop_key+1) % len(keys)
                stop_index = keys.index(stop_key)
            current_row += 1
        current_row = 0
        stop_key = 0
        stop_len = len(keys) - keys.index(stop_key)
        while current_row < num_rows:
            d_rows[current_row] += list(text[text_index:text_index+stop_len])
            text_index += stop_len
            stop_len -= 1
            if stop_len < 1:
                stop_key += 1
                stop_len = len(keys) - keys.index(stop_key)
                current_row += 1
            current_row += 1
        d_rows[-1] += ['']*(len(keys)-len(d_rows[-1]))
        columns = []
        for j in range(len(keys)):
            columns += [''.join(i[j]for i in d_rows)]
    else:
        columns = ['']*len(keys)
        for t in range(len(text)):
            columns[t%len(keys)] += text[t]
    res = [0]*len(keys)
    for index in range(len(keys)):
        res[keys[index]] = columns[index]
    return''.join(res)

def checkerboard(message, seq, word, null):
    trans = {".":seq[-2:], "#":seq[-1]*2};res='';j=z=0
    for x in range(26):
        v = chr(x + 65)
        if v in word:
            trans[v] = seq[word.index(v)]
        else:
            trans[v] = seq[z-2] + seq[j]
            j += z
            z = (z+1) % 2
    for i in message:
        if i.isdigit():
            res += i
        else:
            res += trans[i]
    return res + null[:-len(res)%5]

def vic_cipher(message, keyword, phrase, date, agent, m_id, null):
    s1 = sequent(phrase[:10])
    s2 = sequent(phrase[10:20])
    a = ''.join(str((int(m_id[i])-int(date[i]))%10) for i in range(5))
    g = ''.join(str((int(a[i])+int(s1[i]))%10) for i in range(10))
    t = ''.join(str(s2[int(g[i])]) for i in range(10))
    u = chain_add(t,60)[10:]
    p = agent+int(u[-2])
    q = agent+int(u[-1])
    seqT = sequent(t)
    v = transpose(u,seqT)
    k1 = sequent(v[:p])
    k2 = sequent(v[p:p+q])
    c = ''.join(str(i)for i in sequent(u[40:]))
    x = checkerboard(message,c,keyword,null)
    y = transpose(x,k1)
    z = transpose(y,k2,1)
    e = [z[5*i:5*(i+1)] for i in range(-(-len(z)//5))]
    X = 1-int(date[-1])
    return ' '.join(e[:X] + [m_id] + e[X:])
Sherlock9
fuente
2
Python 3 permite caracteres unicode como variables, FYI.
Paul
Cambiar ord(seq[i])+ord(seq[i+1])a sum(map(ord,seq[i:i+2]))guardar 1 personaje, creo.
3

C, 2880 2769 2766 2762 2743 2741 2739 2699 2458 bytes

#include<stdio.h>
#define m(x)malloc(x)
#define Y(x)strlen(x)
typedef int i;typedef char*c;c _(c A,i B,i D){if(D>=B){return A;}c C=m(Y(A)+2);sprintf(C,"%s%c",A,48+(A[D]+A[D+1]-96)%10);return _(C,B,D+1);}c l(c A){i J=Y(A);c P=m(J+2);for(i m=0;m<J;m++){P[m]=32;}for(i v=0;v<J;v++){char G;i R;for(i u=0;u<J;u++){R=u<1|A[u]<G?u:R;G=u<1|A[u]<G?A[u]:G;}P[R]=48+v;c V=m(J);for(i t=0;t<J;t++){V[t]=t!=R?A[t]:97;}A=V;}return P;}c S(c C,c N,c I,char U){srand(time(NULL));i M=Y(I);i O=Y(N);i R=rand()%M;c Q=m(M+1);for(i u=R;u<M;u++){Q[u-R]=I[u];}Q[M-R]=46;for(i H=0;H<R;H++){Q[H+M-R+1]=I[H];}c g=m(28);c V=m(28);strcat(V,C);sprintf(g,"%s%s",N,"BCDFGHJKLMPQUVWXYZ.#");i B=Y(N);for(i q=B;q<10;q++){for(i x=0;x<10;x++){char J[2]={C[q],C[x]};V[B]=48+atoi(J);B++;}}c w=m(M*2+4);for(i J=0;J<=M;J++){i K=0;for(i X=0;X<28;X++){if(Q[J]==g[X]){char F[3];sprintf(F,"%d",V[X]-48);strcat(w,F);K=1;}}if(K<1){w[Y(w)]=Q[J];}}i f=Y(w);if(f%5>0){c P=m(5-f%5);for(i E=0;E<5-f%5;E++){P[E]=U;}strcat(w,P);}return w;}c a(c I,c U){i M=Y(I),K=Y(U);c T=m(M);i F=0;for(i b=0;b<K;b++){for(i y=0;y<K;y++){if(U[y]==48+b){for(i u=y;u<M;u+=K){T[F]=I[u];F++;}}}}return T;}c da(c I,c K){i e=Y(I),k=Y(K);c T=m(e);for(i y=0;y<e;y++){T[y]=32;}i F,P;F=P=0;for(i u=0;u<k;u++){for(i v=0;v<k;v++){T[F]=I[P];P++;F++;if(K[v+1]-48==u){for(i C=1;C<k-v;C++){F+=k-v-C;for(i E=0;E<=v+C;E++){if(F<e&P<e){T[F]=I[P];}F++;P++;}}break;}}if(F>e){break;}}i U=0;for(i g=0;g<e;g++){U=T[g]-48<10&-1<T[g]-48?U+1:U;}for(i j=U;j<e;j++){for(i x=0;x<e;x++){if(T[x]==32){T[x]=I[j];break;}}}return a(T,K);}En(c n,c m,c k,i d,c v,c s,char u){c S1,S2;S1=m(10);S2=m(10);for(i i=0;i<20;i++){if(i<10){S1[i]=k[i];}else{S2[i-10]=k[i];}}S1=l(S1);S2=l(S2);c M=m(5);for(i i=4;i>-1;i--){M[i]=48+(s[i]-v[i])%10;}c G=_(M,5,0);for(i y=0;y<10;y++){G[y]=48+(S1[y]+G[y]-96)%10;}c N="0123456789";c T=m(10);for(i q=0;q<10;q++){for(i t=0;t<10;t++){if(N[t]==G[q]){T[q]=S2[t];}}}c Z=_(T,50,0);c U=m(50);for(i h=0;h<50;h++){U[h]=Z[h+10];}i p,q;for(i b=49;b>10;b++){if(U[b]!=U[b-1]){q=d+U[b]-48;p=d+U[b-1]-48;break;}}c V=m(50);i Ct=0;for(i j=0;j<10;j++){for(i o=0;o<10;o++){if(l(T)[o]==48+j){for(i x=o;x<o+41;x+=10){V[Ct]=U[x];Ct+=1;}}}}c K1=m(p);c K2=m(q);for(i D=0;D<p+q;D++){if(D<p){K1[D]=V[D];}else{K2[D-p]=V[D];}}K1=l(K1);K2=l(K2);c C=m(10);for(i b=40;b<50;b++){C[b-40]=U[b];}C=l(C);c t=da(a(S(C,m,n,u),K1),K2);i O=0;for(i B=0;B<Y(t)/5+1;B++){if(B==Y(t)/5-v[Y(v)-1]+49){printf("%s ",s);}else{for(i J=O;J<O+5;J++){printf("%c",t[J]);}printf(" ");O+=5;}}}

Dios mío. Este es el programa más largo que he tenido para jugar golf. Este es también el primero en el que realmente me quedé sin nombres de variables de un solo carácter para el alcance global y, por lo tanto, tuve que pasar a usar algunos de 2 caracteres (el hecho de que aparentemente no puedo redeclarar variables no ayuda). Por lo tanto, los consejos de golf son muy apreciados.

Sin golf

Compila sin ninguna advertencia, a diferencia de la versión de golf. Los cambios menores realizados en la versión de golf no se reflejarán en esta versión sin golf.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

char*Chain_Add(char*String,int End,int Start){
  if(Start>=End){return String;}
  char*C=malloc(strlen(String)+2);
  sprintf(C,"%s%c",String,'0'+(((String[Start]-'0')+(String[Start+1]-'0'))%10));
  return Chain_Add(C,End,Start+1);
}

char*Sequent(char*String){
  int J=strlen(String);
  char*P=malloc(J+2);
  for(int m=0;m<J;m++){
    P[m]=' ';
  }
  for(int v=0;v<J;v++){
    char G;
    int R;
    for(int u=0;u<J;u++){
      R=(u<1||String[u]<G)?u:R;
      G=(u<1||String[u]<G)?String[u]:G;
    }
    P[R]='0'+v;
    char*V=malloc(J);
    for(int t=0;t<J;t++){
      if(t!=R){
    V[t]=String[t];
      }
      else{
    V[t]='a';
      }
    }
    String=V;
  }
  return P;
}

char*Straddling_Checkerboard(char*C,char*Key,char*Message,char null){
  srand(time(NULL));
  int Msg_Len=strlen(Message);
  int Key_Len=strlen(Key);
  int R=rand()%Msg_Len;
  char*Q=malloc(Msg_Len+1);
  for(int u=R;u<Msg_Len;u++){
    Q[u-R]=Message[u];
  }
  Q[Msg_Len-R]='.';
  for(int H=0;H<R;H++){
    Q[H+Msg_Len-R+1]=Message[H];
  }
  char*Alphabet=malloc(26);
  for(int W=0;W<26;W++){
    Alphabet[W]='A'+W;
  }
  int q=0;
  char*e=malloc(Key_Len);
  for(int z=0;z<Key_Len;z++){
    if(strchr(e,Key[z])!=NULL){
      q++;
    }
    else{
      e[z-q]=Key[z];
    }
  }
  int r=0;
  for(int h=0;h<26;h++){
    if(strchr(e,Alphabet[h-r])!=NULL){
      for(int X=h-r;X<26;X++){
    Alphabet[X]=Alphabet[X+1];
      }
      r++;
    }
  }
  char*Checkerboard=malloc(28);
  for(int i=0;i<26;i++){
    if(i<strlen(e)){
      Checkerboard[i]=e[i];
    }
    else{
      Checkerboard[i]=Alphabet[i-strlen(e)];
    }
  }
  Checkerboard[26]='.';
  Checkerboard[27]='#';
  char*Values=malloc(28);
  strcat(Values,C);
  int B=strlen(e);
  for(int q=B;q<10;q++){
    for(int x=0;x<10;x++){
      char J[2]={C[q],C[x]};
      Values[B]='0'+atoi(J);
      B++;
    }
  }
  char*Encoded=malloc(Msg_Len*2+4);
  for(int J=0;J<=Msg_Len;J++){
    int K=0;
    for(int X=0;X<28;X++){
      if(Q[J]==Checkerboard[X]){
    char F[3];
    sprintf(F,"%d",Values[X]-'0');
    strcat(Encoded,F);
    //printf("F = %s while Q[J] = %c and Checkerboard[X] = %c and Encoded = %s\n",F,Q[J],Checkerboard[X],Encoded);
    K=1;
      } 
    }
    if(K<1){
      Encoded[strlen(Encoded)]=Q[J];
    }
  }
  int Encded_Len=strlen(Encoded);
  if(Encded_Len%5>0){
    char*P=malloc(5-Encded_Len%5);
    for(int E=0;E<5-Encded_Len%5;E++){
      P[E]=null;
    }
  strcat(Encoded,P);
  }
  return Encoded;
}

char*Transpose(char*Message,char*K1){
  int Msg_Len=strlen(Message),K1_Len=strlen(K1);
  char*T=malloc(Msg_Len);
  int F=0;
  for(int i=0;i<K1_Len;i++){
    for(int y=0;y<K1_Len;y++){
      if(K1[y]=='0'+i){
    for(int u=y;u<Msg_Len;u+=K1_Len){
      T[F]=Message[u];
      F++;
    }
      }
    }
  }
  return T;
}

char*Disrupted_Transpose(char*Message,char*K2){
  int Msg_Len=strlen(Message),K2_Len=strlen(K2);
  char*T=malloc(Msg_Len);
  for(int y=0;y<Msg_Len;y++){
    T[y]=' ';
  }
  int F=0;
  int P=0;
  for(int u=0;u<K2_Len;u++){
    for(int v=0;v<K2_Len;v++){
      T[F]=Message[P];
      P++;F++;
      if(K2[v+1]-'0'==u){
        for(int C=1;C<K2_Len-v;C++){
      F+=K2_Len-v-C;
      for(int E=0;E<=v+C;E++){
        if(F<Msg_Len&P<Msg_Len){
          T[F]=Message[P];
        }
        F++;P++;
      }
    }
    break;
      }
    }
    if(F>Msg_Len){
      break;
    }
  }
  int U=0;
  for(int g=0;g<Msg_Len;g++){
    U=(T[g]-'0'<10&-1<T[g]-'0')?U+1:U;
  }
  for(int j=U;j<Msg_Len;j++){
    for(int x=0;x<Msg_Len;x++){
      if(T[x]==' '){
    T[x]=Message[j];
    break;
      }
    }
  }
  return Transpose(T,K2);
}

void VIC_Encoder(char*Message,char*Phrase,char*Key,int a_id,char*date,char*m_id,char null){
  char*S1=malloc(10);
  char*S2=malloc(10);
  for(int i=0;i<20;i++){
    if(i<10){
      S1[i]=Key[i];
    }
    else{
      S2[i-10]=Key[i];
    }
  }
  S1=Sequent(S1);
  S2=Sequent(S2);
  char*M=malloc(5);
  for(int i=4;i>-1;i--){
    M[i]='0'+(((m_id[i]-'0')-(date[i]-'0'))%10);
  }
  char*G=Chain_Add(M,5,0);
  for(int y=0;y<10;y++){
    G[y]='0'+(((S1[y]-'0')+(G[y]-'0'))%10);
  }
  char*N="0123456789";
  char*T=malloc(10);
  for(int q=0;q<10;q++){
    for(int t=0;t<10;t++){
      if(N[t]==G[q]){
    T[q]=S2[t];
      }
    }
  }
  char*Z=Chain_Add(T,50,0);
  char*U=malloc(50);
  for(int h=0;h<50;h++){
    U[h]=Z[h+10];
  }
  int p,q;
  for(int b=49;b>10;b++){
    if(U[b]!=U[b-1]){
      q=a_id+(U[b]-'0');
      p=a_id+(U[b-1]-'0');
      break;
    }
  }
  char*seqT=Sequent(T);
  char*V=malloc(50);
  int Count=0;
  for(int j=0;j<10;j++){
    for(int o=0;o<10;o++){
      if(seqT[o]=='0'+j){
    for(int x=o;x<o+41;x+=10){
      V[Count]=U[x];
      Count+=1;
    }
      }
    }
  }
  char*K1=malloc(p);
  char*K2=malloc(q);
  for(int D=0;D<p+q;D++){
    if(D<p){
      K1[D]=V[D];
    }
    else{
      K2[D-p]=V[D];
    }
  }
  K1=Sequent(K1);
  K2=Sequent(K2);
  char*C=malloc(10);
  for(int b=40;b<50;b++){
    C[b-40]=U[b];
  }
  C=Sequent(C);
  char*Transposed_2=Disrupted_Transpose(Transpose(Straddling_Checkerboard(C,Phrase,Message,null),K1),K2);
  int O=0;
  for(int B=0;B<strlen(Transposed_2)/5+1;B++){
    if(B==strlen(Transposed_2)/5-date[strlen(date)-1]+'1'){
      printf("%s ",m_id);
    }
    else{
      for(int J=O;J<O+5;J++){
    printf("%c",Transposed_2[J]);
      }
      printf(" ");
      O+=5;
    }
  }
}

Notas

  • Esto utiliza un tablero similar al siguiente para codificar el mensaje:

      3 4 5 6 2 3 4 5 6 7
      S E N A T O R I     
    6 B C D F G H J K L M 
    7 P Q U V W X Y Z . #
    
  • Esto supone que todas las cadenas aplicables se dan en mayúsculas. El mensaje también debe tener todos los signos de puntuación, excepto los períodos eliminados y todos los números demarcados por #s, mientras que la frase clave debe tener todos los signos de puntuación eliminados.

  • El mensaje codificado resultante se envía a STDOUT como una cadena de grupos de cinco dígitos separados por espacios.

  • El mensaje de entrada debe estar en inglés.

  • Hubiera combinado algunas de las funciones que usé, pero luego tendría que recurrir al uso de más nombres de variables de dos letras, haciendo que el programa final sea más largo de lo que sería con algunas funciones más.

  • Actualmente, esto no supone que la palabra clave (al menos en inglés) siempre contendrá el mismo conjunto de letras, y lo compensa eliminando duplicados, manipulando el tablero de ajedrez, etc. Esta capacidad aparentemente no es requerida por OP, así que actualmente estoy jugando al golf con los bytes adicionales e innecesarios que está ocupando. Actualizado para la versión de golf.

R. Kap
fuente
2

JavaScript (ES6), 946 938 953 bytes

V=(c,d,f,g,j,k,m)=>{S=a=>a.split``,J=a=>a.join``,A=(a,b)=>{for(i=0;a[L="length"]<b;a+=(a[i++]- -a[i])%h);return a},Q=b=>(a=S(b).sort(),S(b).map(b=>a[i=a[X="indexOf"](b)]=i)),u=A(t=J(S(A(J(S(k).map((a,b)=>Math.abs(a-g[b]))),h=10)).map((a,b)=>Q(f[C="slice"](h,20))[(Q(f[C](0,h))[b]- -a)%h])),60)[C](h),T=((a,b,c)=>{if(r=Array(l=b[L]).fill(""),c){for(e=a[L]/l,i=0,w=[],u=R=b[X](x=0);i<e;)w[i++]=a[P](0,R++),u?u=0:R>l||(R=b[X](u=++x));for(i=0;i<e;)w[i]=J(w[i].concat(a[P](0,l-w[i++][L])));a=J(w)}for(i in a)r[+b[i%l]]+=a[i];return r}),v=J(T(u,Q(t))),q=J(Q(u[C](-h))),t="ABCDEFGHIJKLMNOPQRSTUVWXYZ#".match(new RegExp("[^"+d+"]","g")),t[P="splice"](9,0,"."),M=[];for(i in t)M[t[i]]=q[8^i/h]+(M[d[i]]=q[i%h]);for(n=c[L],b=J((c[C](n-=new Date%n)+"."+c[C](0,n)).split(/ |/).map(a=>M[a]||a)),b+=m.repeat(5-b[L]%5),i=f=q=49;f==q;)f=+u[i-1]+j,q=+u[i++]+j;return t=J(T(S(J(T(b,Q(v[C](0,f))))),Q(v.substr(f,q)),1)).match(/.{5}/g),g=-g[C](-1),g++&&t[P](g||t[L],0,k),t}

Vi durante el fin de semana que todavía no había una entrada de JS para esto, así que aquí está mi intento (de último minuto). ¡Implementar y jugar golf fue tan loco como divertido!

Fragmento de demostración

Editar: -8 bytes

Se dio cuenta de que había paréntesis adicionales alrededor de la función S,J,A,Q

Editar: +15 bytes

Se actualizó la lógica de cómo message idse coloca en el mensaje final (ahora 1 indexado y 0 no lo incluye en la salida).

Sin golf

chainAdd = (s,l)=>{for(i=0;s.length<l;s+=(s[i++]- -s[i])%10);return s;}

sequentialize = (s)=> {
    a=s.split('').sort();
    return s.split('').map(c=>(i=a.indexOf(c),a[i]='',i));  
}

transpose = (s,k,disruptive)=>{
    var result=Array(k.length).fill('')
    if(disruptive){
        rows=[]
        k_index=0;
        rowLength=k.indexOf(k_index);
        triangling=!rowLength;

        expectedRows = s.length/k.length
        for(row=0;row<expectedRows;row++){
            rows[row]=s.splice(0,rowLength++)
            if(triangling){     
                if(rowLength>k.length){
                    triangling=false;
                    rowLength=k.indexOf(++k_index)              
                }
            }
            else{               
                triangling=true;
            }
        }

        for(row=0;row<expectedRows;row++){
            rows[row]= rows[row].concat(s.splice(0,k.length-rows[row].length)).join('')
        }
        s=rows.join('')
    }
    for(i in s)
        result[+k[i%k.length]]+=s[i];   
    return result;
}

checkerboard =(message,seq, keyword, nulls)=>{  
    t='ABCDEFGHIJKLMNOPQRSTUVWXYZ#'.match(new RegExp('[^'+keyword+']','g'));
    t.splice(9,0,'.')

    map=[]
    for(i in t)
        map[t[i]]=(seq[8^(i/10)])+(map[keyword[i]]=seq[i%10])

    r = new Date%message.length;
    rotateMessage=message.substr(message.length-r)+'.'+message.substr(0,message.length-r)

    result =rotateMessage.split(/ |/).map(x=>map[x]||x).join('');
    result+=nulls.repeat(5-result.length%5)

    return result;
}

vic = (message, keyword, phrase, date, agent, m_id, nulls)=>{
    s1=sequentialize(phrase.substr(0,10))//.join('')
    s2=sequentialize(phrase.substr(10,10))//.join('')

    r = m_id.split('').map((x,i)=>Math.abs(x-date[i])).join('')
    g = chainAdd(r,10).split('').map((x,i)=>(s1[i]- -x)%10);

    t = g.map(i=>s2[+i]).join('');
    u=chainAdd(t,60).substr(10)

    var p,q;
    for(i=49;p==q;i++){
        p=agent + +u[i-1];
        q=agent + +u[i];
    }
    seqT = sequentialize(t);
    v=transpose(u,seqT).join('');

    k1 = sequentialize(v.substr(0,p));
    k2 = sequentialize(v.substr(p,q));
    c  = sequentialize(u.substr(-10)).join('')

    CB =checkerboard(message,c, keyword, nulls);
    t1=transpose(CB,k1).join('')
    t2=transpose(t1.split(''),k2,1).join('').match(/.{5}/g);
    (d=-date.substr(-1))&&t2.splice((d+1)||t2.length,0,m_id);
    return t2;
}

Notas

  • Esto utiliza un tablero similar al siguiente para codificar el mensaje:

      3 1 0 5 9 6 8 7 2 4
      S E N A T O R I
    2 B C D F G H J K L .
    4 M P Q U V W X Y Z #
    
  • Todas las cadenas se dan en mayúsculas. El mensaje es latín alfanumérico (más .y #) y debe eliminarse toda la puntuación (excepto los puntos). Todos los números ya deberían estar marcados con #s. La frase clave debe tener todos los signos de puntuación / espacios eliminados.

  • El mensaje resultante se devuelve como una matriz de cadenas de 5 dígitos.

Mejoras

  • Siento que hay una manera de abusar de "Todos los idiomas" para guardar algunos bytes. Si tuviera más tiempo, volvería a configurar esto para asumir que el idioma era algo como el hawaiano, que solo tiene 12 letras.

  • Cualquier sugerencia de golf es siempre bienvenida.

SLuck49
fuente
¿Podría agregar un fragmento para que pueda verificar que esto funciona? Si es así, entonces puedo otorgarle la recompensa.
R. Kap
@ R.Kap Claro, agregué un fragmento de demostración
SLuck49 el
Hmm ... en la demostración, message identifierparece estar 7lejos del final en lugar de 6. Además, en su versión sin golf, lo mismo Idparece estar 6lejos del principio en lugar del final.
R. Kap
@ R.Kap Sí, hubo un error cuando lo publiqué por primera vez (no debe haberlo solucionado en ungolf). En cuanto al golf, supuse que estaba indexado en 0 porque de lo contrario si 1significa el final, ¿dónde diría que message identifierdebería irse a 0? Puedo cambiarlo, solo necesito saberlo.
SLuck49
Yo diría que en una 0la message identifierdebe omitirse de la salida.
R. Kap
1

Clojure, 1197 1212 bytes

Ough, estoy agotado.

Actualización: se agregó la ubicación de división aleatoria requerida del mensaje, la versión no protegida utiliza la misma ubicación que el ejemplo dado para que el algoritmo se pueda verificar fácilmente.

(defn enc[I K E D Y M](let[P split-at A concat Z zipmap R partition W mapcat % count X repeat O vector / map x(fn[C](apply / O C))G range t 10 r(G t)m(fn[i](mod i t))F(fn[[n & N]](/ last(iterate(fn[[[b & N]a]][(A N[(m(+ a b))])b])[N n])))Q(fn[S](for[i(G(% S))a[(nth S i)]](apply +(%(filter #{a}(take i S)))(for[b S :when(pos?(compare a b))]1))))[S J](/ Q(P t(take 20 E)))T(/(Z r J)(/ m(/ + S(F(/ - M D)))))U(take 50(drop t(F T)))l(last U)p(+ Y(last(remove #{l}U)))V(W(Z(Q T)(x(R t U)))r)[k j](/ Q(P p(take(+ p Y l)V)))B(into(Z(/ char(G 48 58))(G))(/(fn[i c][c(+(*(quot i 10)20)(nth(Q(reverse(take t(reverse U))))(m i)))])(G)(A(str K",,")(remove(set K)(/ char(A(G 65 91)".#"))))))?(% k)T(vec(filter some?(W(Z k(x(R ?(A(flatten(R 5(A(W str(/ B(let[[b e](P(rand-int(count I))I)](apply str(A e".. "b)))))(X 4(B\,)))))(X(dec ?)nil)))))(G ?))))w (% j)NR(+(quot(% T)w)1)L(flatten(for[k r](for[i(G(.indexOf j k)(inc w))](G i))))C(for[[r c](/ O(rest(reductions + -1(/(fn[i](get{0 1}i 0))L)))L):when(< r NR)][r c])H(R 5(filter some?(W(Z j(x(R w (A(vals(into(sorted-map)(/ O(A C(for[i(G NR)j(G w)c[[i j]]:when(not((set C)c))]c))T)))(X(dec w)nil)))))(G w))))](/(fn[p](apply str p))(let[[b e](P(-(% H)(D 6)-1)H)](A b[M]e)))))

Entradas de muestra y caso de prueba:

(def mymsg (clojure.string/upper-case "We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot#3#"))
(def mykey "SENATORI")
(def mypharase (clojure.string/upper-case (apply str (remove #{\space} "The first principle is that you must not fool yourself — and you are the easiest person to fool."))))
(def mydate [3 1 7 2 0 1 6])
(def mynum 9)
(def M [4 7 9 2 1])

;("61231" "12824" "71192" "58609" "92185" "48612" "14927" "22944" "34046" "13348" "04159" "38645" "70546" "20254" "22026" "64584" "21904" "47921" "90253" "42694" "42221" "56644" "14541")
(enc mymsg mykey mypharase mydate mynum M)

Sin golf:

(defn enc[mymsg mykey mypharase mydate mynum M]
  (let[t       10
       r       (range t)
       m       (fn[i](mod i t))
       lagfib  (fn[[n & N]](map last(iterate(fn[[[b & N]a]][(concat N[(m(+ a b))])b])[N n])))
       toseq   (fn[S](for[i(range(count S))a[(nth S i)]](apply +(count(filter #{a}(take i S)))(for[b S :when(pos?(compare a b))]1))))
       [S1 S2] (map toseq(split-at t(take 20 mypharase)))
       M2      (take t(lagfib(map - M mydate)))
       G       (map m(map + S1 M2))
       Gmap    (zipmap r S2)
       T       (map Gmap G)
       U       (take 50(drop t(lagfib T)))
       L2      (last U)
       L1      (last(remove #{L2}U))
       p       (+ mynum L1)
       q       (+ mynum L2)
       seqT    (toseq T)
       V       (mapcat(zipmap seqT(apply map vector(partition t U)))r)
       [K1 K2] (map toseq(split-at p(take(+ p q)V)))
       C       (toseq(reverse(take t(reverse U))))
       B       (into(zipmap(map char(range 48 58))(range))(map(fn[i c][c(+(*(quot i 10)20)(nth C(m i)))])(range)(concat(str mykey",,")(remove(set mykey)(map char(concat(range 65 91)".#"))))))
      ;B       (into(zipmap(map char(range 48 58))(range))(map(fn[i c][c(+(nth C(quot i 3))(*(mod i 3)20))])(range)(flatten(apply map vector(partition 10(apply concat mykey",,"(apply map vector (partition 2(remove(set mykey)(map char(concat(range 65 91)".#")))))))))))
       N1      (count K1)
       mymsg   (flatten(partition 5(concat(mapcat str(map B(let[[b e](split-at 49 mymsg)](apply str(concat e".. "b)))))(repeat 4(B\,)))))
       T1      (vec(filter some?(mapcat(zipmap K1(apply map vector(partition N1(concat mymsg(repeat(dec N1)nil)))))(range N1))))
       N2      (count K2)
       NR      (+(quot(count T1)N2)1)
       cols    (flatten(for[k r](for[i(range(.indexOf K2 k)(+(count K2)1))](range i))))
       rows    (rest(reductions + -1(map(fn[i](get{0 1}i 0))cols)))
       coords  (for[[r c](map vector rows cols):when(< r NR)][r c])
       coords  (concat coords(for[i(range NR)j(range N2)c[[i j]]:when(not((set coords)c))]c))
       T2      (partition 5(filter some?(mapcat(zipmap K2(apply map vector(partition N2(concat(vals(into(sorted-map)(map vector coords T1)))(repeat(dec N2)nil)))))(range N2))))]
    (map(fn[p](apply str p))(let[[b e](split-at(-(count T2)(mydate 6)-1)T2)](concat b[M]e)))))

Tiene una implementación alternativa en el tablero de ajedrez Bque es la misma que en la definición de tarea. Pero el envío utiliza otro en el que los alfabetos no utilizados primero llenan la segunda fila y luego la tercera en lugar de llenar columna por columna.

NikoNyrh
fuente
Pensé en escribir una solución Clojure, pero mi cabeza explotó mientras leía la pregunta. ¿Cuánto tiempo llevó eso escribir?
Carcigenicate
Tal vez 3 horas mientras ves Youtube en el lateral. Esto comenzó bastante fácil, pero estaba a punto de rendirme cuando tuve que implementar la segunda "transposición interrumpida". Ahora eso coordsse genera dos veces, primero generando la forma triangular y luego rellenando las coordenadas que faltaban. Además, el "relleno hasta la longitud de la multiplicación de N" podría tener una solución más elegante que la concatenación de elementos N - 1 y la división en longitudes de N.
NikoNyrh
Oh, maldita sea, olvidé cambiar el punto de división codificado en (split-at 49 mymsg), 49 debería ser algo (rand-int(count mymsg))así como la respuesta correcta sería un poco más de 1200 bytes. zzz
NikoNyrh
Maldición. Sin embargo, probablemente aún menos que la respuesta c.
Carcigenicate