Cifrar:
ffii{{~~__:0a('0'*!.0a('0'*22(!'(~$~_:}-}$-a*}+{{if~~:i:0({}?;__:{}84{}*__({}?\__:{} _{}70{}g_{})_{}?\4__{}8*-_{}+{}80{}g_%4_{}8*{}+\\sl||||||||||||||||||||||||||||9||||||||||||||9||||||||||||||||||||||||||||||||||||||||||||||||||||9
> > >!;7f7-_{}!%_{}!<872-d_{}!&_{}!<[755(7(%~~_{}!<[55(7(_{}!*!*23a(_{}!'_{}!"55(7((~~_{}~~~o__'4'0.{{{o,
Descifrar:
iill~~""bb=3d+*3*-$13d+*3*-55+$*+"'"b=!0!'0d-!.~~li""=l=3+~!B>bb=~!;7~!-bb+~!B_bb=~!#b~!:3~!jb~!,b~!B_7bb~!;-0b~!.~!;3~!jb(7b~!;-~!.__vo < < <
##############################################################################A######################A##############################A$>:i:0b~!$(b~!$?;:50gb~!$)b~!$?^:88+:+(""b~!$?^88+:+b~!$-$-56d+b~!$*b~!$%88+:++""b~!"""rbb*7*31~~~r/
Los dos programas están compensados por 3, y toman la entrada de la forma:
<2-digit offset> <text>
El desplazamiento debe ser de 2 dígitos, por lo que se debe ingresar un desplazamiento de 5 como 05
.
Esta es una presentación larga, pero casi todos los caracteres sin relleno son utilizados por ambos programas . Hay mucho espacio en blanco que definitivamente se puede jugar, pero pensé que el programa sería más interesante de esta manera.
Esta imagen resalta los caracteres utilizados por ambos programas.
Explicación
La construcción principal que hace esto posible es _{} -> b~!
, lo que permite omitir arbitrariamente los caracteres en el programa de descifrado. ¿Cómo?
Encrypt:
_ : Mirror, but is a no-op if the program flow is horizontal
{ : Shift stack left
} : Shift stack right
Decrypt:
b : Push 11 to stack
~ : Pop top of stack
! : Skip the next instruction
Con todo, el programa de cifrado no hace nada, pero el programa de descifrado omite la siguiente instrucción. Esto puede extenderse a _{}! -> b~!$
, lo que permite omitir caracteres de forma arbitraria en el programa de cifrado .
Aparte de esto, la mayoría del resto del programa está presionando números, realizando operaciones en esos números y luego encontrando formas de hacerlos explotar. Por ejemplo, una construcción útil es ~~ -> ""
, que muestra dos valores para el programa de cifrado, pero no introduce nada en el programa de descifrado.
> <>, 149 bytes
Aquí está la versión menos interesante, que utiliza el hecho de que las instrucciones que no se pasan son efectivamente comentarios en lenguajes 2D.
Cifrar:
i68*:@-a*i@@-+i~v
4:v?)g31:;?(0:i:/8
(?v48*-+03g%48*+\*
_~\of0. .1+1fo/
j*+:zq<6B99A6=qz6g
53Ji?C58/8;?r0?C5:
C?EiJ4r?<EFJ3;EtEg
:tAC5EK8l5tKK86t*i
Descifrar:
^+-~/5"V~^55" ^sk
)/k4}\(&/04|%/^/$-
|4k)-~" %(\y)-~ Q~
TsQd[%#ttt#& &[d$
_~ /of1+7..6+2fo+\
*(?^48*-$-04g%48*/
84:^?)g41:;?(0:i:\
/i68*:@-a*i@@-+i~^
Los dos programas están compensados por 84 y toman la entrada de la misma manera que arriba. La primera instrucción decide qué mitad del programa ejecutar, con i
(entrada) manteniendo el flujo del programa hacia la derecha en el programa de cifrado, y ^
redirigiendo el flujo del programa hacia arriba (dando vueltas y regresando desde la parte inferior) en el programa de descifrado.
Explicación
Para la mitad relevante del programa de cifrado (el programa de descifrado es similar):
i read first input digit as char
68*:@-a* subtract 48 (ASCII "0") and multiply by 10, keeping another 48 on the stack
i read second input digit as char
@@-+ subtract 48 and add to 10*(first digit), giving the offset
i~ read in space and discard it
--- LOOP ---
: copy the offset
i: read input char
:0)?; check if less than 0 (i.e. EOF) and terminate if so
:13g)?v check if greater than ~ in cell (1,3) and drop down if so
48*(?v check if less than 32 and drop down if so
48*-+03g%48*+ calculate Caesar shift of the char, fetching 95 from (0,3)
of1+1. repeat loop
of0. repeat loop
Herramienta de codificación
Esto no está relacionado con el resto de la publicación anterior, pero pensé en publicar esto porque necesito usarlo: P
for(var i=0;i<95;++i){var option=document.createElement("option");option.text=i;document.getElementById("offset").add(option)};function update(m){if(m==1)var code=document.getElementById("in").value;else var code=document.getElementById("out").value;var offset=parseInt(document.getElementById("offset").value);var output="";for(var i=0;i<code.length;i++){var n=code[i].charCodeAt(0);if(n<32||n>127)output+=code[i];else{var c=(n-32+offset*m)%95;output+=String.fromCharCode(c<0?c+95+32:c+32)}}if(m==1)document.getElementById("out").value=output;else document.getElementById("in").value=output};
<html><body><textarea id="in" onkeyup="update(1)" rows=5 style="width:100%"></textarea><textarea id="out" rows=5 style="width:100%" onkeyup="update(-1)"></textarea><select id="offset" onchange="update(1)"></select></body></html>