Munge mi contraseña

17

Aún se deben evitar las palabras comunes para usarlas como contraseñas. Este desafío es acerca de la codificación de un programa muy simple que munges una contraseña dada ( M odificar U asta N ot G uessed E asily).

Entrada

Una palabra, que es una cadena escrita en el alfabeto abcdefghijklmnopqrstuvwxyz. No importa si las letras son minúsculas o mayúsculas.

Munging

  1. Cambie cualquier secuencia repetida de una misma letra a sí misma precedida por el número de veces que la letra se repitió ( LLLLcon 4L)
  2. Cambia el primero acon@
  3. Cambia el primero bcon8
  4. Cambia el primero ccon(
  5. Cambia el primero dcon6
  6. Cambia el primero econ3
  7. Cambia el primero fcon#
  8. Cambia el primero gcon9
  9. Cambia el primero hcon#
  10. Cambia el primero icon1
  11. Cambia el segundo icon!
  12. Cambia el primero kcon<
  13. Cambia el primero lcon1
  14. Cambia el segundo lconi
  15. Cambia el primero ocon0
  16. Cambia el primero qcon9
  17. Cambia el primero scon5
  18. Cambia el segundo scon$
  19. Cambia el primero tcon+
  20. Cambia el primero vcon>
  21. Cambia el segundo vcon<
  22. Cambia el primero wconuu
  23. Cambia el segundo wcon2u
  24. Cambia el primero xcon%
  25. Cambia el primero ycon?

La regla 1 debe aplicarse la cantidad necesaria de veces hasta que no sea posible aplicarla más. Después de eso se aplica el resto de las reglas.

Salida La palabra munged

Ejemplos

  • codegolf -> (0639o1#
  • programming -> pr09r@2m1ng
  • puzzles -> pu2z135
  • passwords -> p@25uu0r6$
  • wwww -> 4uu
  • aaaaaaaaaaa -> 11a
  • lllolllolll -> 3103io3l
  • jjjmjjjj -> 3jm4j

Este es el , ¡así que haga su programa lo más corto posible!

Nada en esta publicación debe usarse como ideas de contraseña o como parte de las prácticas de contraseña.

mdahmoune
fuente
18
El hecho mismo de que programas como este sean posibles significa que el atacante podría escribirlos y modificar la contraseña (y probar los diversos cambios) con la misma facilidad (incluso más fácil porque a menudo tienen acceso a un mejor hardware). Entonces, solo por seguridad, diré: nada en esta publicación debe usarse como ideas de contraseña o como parte de las prácticas de contraseña.
NH.
1
Recomiendo que el descargo de responsabilidad aparezca en negrita y duplicarlo en la parte superior. Nunca se puede ser demasiado cuidadoso ...
wizzwizz4

Respuestas:

11

Java 8, 237 321 319 280 247 241 240 237 bytes

s->{for(int a[]=new int[26],i=0,l=s.length,t,x;i<l;i+=t){for(t=0;++t+i<l&&s[i]==s[t+i];);System.out.print((t>1?t+"":"")+(++a[x=s[i]-65]>2?s[i]:"@8(63#9#1J<1MN0P9R5+U>u%?ZABCDEFGH!JKiMNOPQR$TU<2XYZ".charAt(x+26*~-a[x])+(x==22?"u":"")));}}

+84 bytes porque las reglas obtuvieron cambios ... ( EDITAR: finalmente de vuelta a mis 237 bytes iniciales ) . Reemplazar WWWWcon 222Wes fácil en Java, pero 4Wno ... Si solo Java tuviera una forma de usar el grupo de captura de expresiones regulares para algo. Obtener la longitud con "$1".length(), reemplazar la coincidencia en sí misma "$1".replace(...), convertir la coincidencia en un número entero con new Integer("$1"), o usar algo similar como Retina (es decir s.replaceAll("(?=(.)\\1)(\\1)+","$#2$1")) o JavaScript (es decir s.replaceAll("(.)\\1+",m->m.length()+m.charAt(0))) sería mi cosa número 1 que me gustaría ver en Java en el futuro en beneficio de codegolfing ..>.> Creo que esta es la décima vez que odio Java no puede hacer nada con la coincidencia del grupo de captura ..
-78 bytes gracias a @ OlivierGrégoire .

I / O es mayúscula.

Explicación:

Pruébalo aquí

s->{                           // Method with String parameter and no return-type
  for(int a[]=new int[26],     //  Array with 26x 0
          i=0,                 //  Index-integer, starting at 0
          l=s.length,          //  Length
          t,x;                 //  Temp integers
      i<l;                     //  Loop (1) over the characters of the input
      i+=t){                   //    After every iteration: Increase `i` by `t`
    for(t=0;++                 //   Reset `t` to 1
        t+i<l                  //   Inner loop (2) from `t+i` to `l` (exclusive)
        &&s[i]==s[t+i];        //   as long as the `i`'th and `t+i`'th characters are equal
    );                         //   End of inner loop (2)
    System.out.print(          //   Print:
     (t>1?t+"":"")             //    If `t` is larger than 1: print `t`
     +(++a[x=s[i]-65]>2?       //    +If the current character occurs for the third time:
       s[i]                    //      Simply print the character
      :                        //     Else:
       "@8(63#9#1J<1MN0P9R5+U>u%?ZABCDEFGH!JKiMNOPQR$TU<2XYZ".charAt(x
                               //      Print the converted character at position `x`
        +26*~-a[x])            //       + 26 if it's the second time occurring
       +(x==22?"u":"")));      //      And also print an additional "u" if it's 'W'
  }                            //  End of loop (1)
}                              // End of method
Kevin Cruijssen
fuente
10

JavaScript (ES6), 147 bytes

s=>[[/(.)\1+/g,m=>m.length+m[0]],..."a@b8c(d6e3f#g9h#i1k<l1o0q9s5t+v>x%y?i!lis$v<".match(/../g),["w","uu"],["w","2u"]].map(r=>s=s.replace(...r))&&s

Casos de prueba

Explicación

Se ejecuta a través de una serie de reemplazos en la cadena de entrada s, en el orden especificado por el desafío. Cada elemento de la serie es una matriz o cadena, con dos elementos, que luego se separa ( ...r) y se pasa as.replace() .

s=>[
    [/(.)\1+/g, m=>m.length + m[0]],// first replacement: transform repeated letters
                                    // into run-length encoding

                                    // string split into length-2 partitions and
                                    // spread into the main array
    ..."a@b8c(d6e3f#g9h#i1k<l1o0q9s5t+v>x%y?i!lis$v<".match(/../g),
                                    // next replacements: all single-char replacements.
                                    // "second" versions are placed at the end so they
                                    //    replace the second instance of that char

    ["w","uu"],["w","2u"]           // last replacements: the two "w" replacements
]
.map(r=> s = s.replace(...r))       // run all replacements, updating s as we go
&& s                                // and return the final string
Justin Mariner
fuente
Muy buena respuesta
mdahmoune
6

05AB1E , 69 bytes

-9 bytes gracias a Emigna

γvygD≠×yÙ}J.•k®zĀÒĀ+ÎÍ=ëµι
•"@8(63#9#1<1095+>%?!i$<"ø'w„uu„2u‚â«vy`.;

Pruébalo en línea!

Okx
fuente
Podrías usar'w„uu„2u‚â
Emigna
¿Podría verificar el resultado para wwww como entrada?
mdahmoune
@mdahmoune 4uu
Sale
Producto cartesiano @Emigna, buena idea.
Okx
La primera parte puede serγvygD≠×yÙ}J
Emigna
6

Perl 5 , 152 + 1 ( -p) = 153 bytes

s/(.)\1+/(length$&).$1/ge;%k='a@b8c(d6e3f#g9h#i1j!k<l1mio0q9r5s$t+u>v<x%y?'=~/./g;for$i(sort keys%k){$r=$k{$i};$i=~y/jmru/ilsv/;s/$i/$r/}s/w/uu/;s/w/2u/

Pruébalo en línea!

Xcali
fuente
Por favor, ¿qué quieres decir con (-p)?
mdahmoune
1
@mdahmoune -pse usa como argumento perlen la línea de comandos que lee automáticamente la entrada STDINy printel contenido de s $_al final del script. TIO permite esa opción, y dado que perl -pe<code>es 1 byte más de perl -e<code>lo que se cuenta como un byte adicional.
Dom Hastings
Creo que has cometido un error tipográfico, ¿no debería ser el ~intermedio j~kun !lugar? Actualmente reemplazó la segunda aparición de icon a en ~lugar de a !.
Kevin Cruijssen
@Xcali #testingonproduction
NieDzejkob
2
@NieDzejkob No hay mejor lugar. Esa es la única forma de saber que funcionará en la producción.
Xcali
4

Probablemente no sea el más golfista posible, pero funciona.

-6 bytes gracias a ovs

-77 Bytes gracias a NieDzejkob y Jonathan French

Python 3 , 329 323 bytes 246 bytes

import re;n=input()
for a in re.finditer('(\w)\\1+',n):b=a.group();n=n.replace(b,str(len(b))+b[0],1)
for A,B,C in[('abcdefghikloqstvxyw','@8(63#9#1<1095+>%?','uu'),('ilsvw','!i$<','2u')]:
	for a,b in zip(A,list(B)+[C]):n=n.replace(a,b,1)
print(n)

Pruébalo en línea!

reffu
fuente
1
Creo que puedes caer.lower()
mdahmoune
Eso tiene sentido, no estaba seguro de si necesitaba manejar mayúsculas o no.
reffugo
321 bytes .
Jonathan Frech
1
320 bytes .
Jonathan Frech
2
En realidad, tu respuesta no funciona. jjjmjjjjdebería dar salida 3jm4jpero da salida 3jm3jj. Editar: 258 bytes con este problema fijo
NieDzejkob
3

Retina , 166124 bytes

(.)\1+
$.&$1
([a-y])(?<!\1.+)
¶$&
¶w
uu
T`l¶`@8(63#9#1j<\1mn0\p9r5+u>\w%?_`¶.
([ilsvw])(?<!\1.+)
¶$&
¶w
2u
T`i\lsv¶`!i$<_`¶.

Pruébalo en línea! Explicación:

(.)\1+
$.&$1

Reemplace una serie de letras repetidas con la longitud y la letra.

([a-y])(?<!\1.+)
¶$&

Haga coincidir la primera aparición de las letras acon yy márquelas con un marcador de posición.

¶w
uu

Arreglar la primera aparición de w.

T`l¶`@8(63#9#1j<\1mn0\p9r5+u>\w%?_`¶.

Fijar la primera ocurrencia de todas las otras letras de aa yy eliminar los marcadores de posición.

([ilsvw])(?<!\1.+)
¶$&

Marque la (originalmente) segunda aparición de las letras i, l, s, v, o wcon un marcador de posición.

¶w
2u

Soluciona la segunda aparición de w.

T`i\lsv¶`!i$<_`¶.

Arregle la segunda aparición de las otras cuatro letras.

Neil
fuente
¿Crees que es posible jugar más al golf?
mdahmoune
@mdahmoune Sí, creo que puedo guardar 33 bytes.
Neil
He votado su respuesta :) será genial si guarda los 33 bytes;)
mdahmoune
@mdahmoune ¡Buenas noticias, en realidad ahorré 42 bytes!
Neil
Genial, tu código es el segundo más corto;)
mdahmoune
3

Haskell , 221 218 213 bytes

($(f<$>words"w2u li i! s$ v< a@ b8 c( d6 e3 f# g9 h# i1 k< l1 o0 q9 s5 t+ v> wuu x% y?")++[r]).foldr($)
f(a:b)(h:t)|a==h=b++t|1>0=h:f(a:b)t
f _ s=s
r(a:b)|(p,q)<-span(==a)b=[c|c<-show$1+length p,p>[]]++a:r q
r s=s

Pruébalo en línea!

Abusos foldrpara ejecutar la cadena a través de una secuencia de transformaciones de cadena hacia atrás. La secuencia "comienza" con la rcual la repetición cuenta el reemplazo al usar spanpara romper la cola de la cuerda cuando deja de ser igual a la cabeza. Si la primera parte de eso no está vacía, es una repetición, así que imprimimos la longitud +1. A continuación, presentamos un argumento fpara cada reemplazo de caracteres en orden (inverso). Los reemplazos se codifican como una sola cadena con el primer carácter como el carácter que se va a reemplazar y el resto como la cadena (ya que los reemplazos w son múltiples caracteres) para ir en su lugar. Puse estas cadenas codificadas en una gran cadena separada por espacios para quewords pueda dividirla en una lista para mí.

EDITAR: ¡Gracias @Laikoni por salvarme 5 bytes! Ese fue un uso inteligente de $lo que no pensé. Tampoco conocía ese <-truco.

usuario1472751
fuente
Gracias por la explicación detallada;)
mdahmoune
1
Puede usar en (p,q)<-span(==a)blugar de let(p,q)=span(==a)by en p>[] lugar de p/=[].
Laikoni
2
Ahorre dos bytes más haciendo mpointfree: ¡ ($(f<$>words"w2u ... y?")++[r]).foldr($) Pruébelo en línea!
Laikoni
2

Lua , 173 bytes

s=...for c,r in("uua@b8c(d6e3f#g9h#i1i!jjk<l1limmnno0ppq9rrs5s$t+v>v<wuuw2ux%y?zz"):gmatch"(.)(.u?)"do s=s:gsub(c..c.."+",function(p)return#p..c end):gsub(c,r,1)end print(s)

Pruébalo en línea!

Ungolfed y explicó:

s = ...


--This string contains every character to replace, followed by
--the character(s) it should be replaced with.
--
--It also contains all characters for which repeated sequences
--of them should be replaced by "<number><character>". That is,
--all letters in the alphabet. This way, a single loop can do
--both the "replace repeated characters" and "encode characters"
--operations, saving a for loop iterating over the alphabet.
--
--Characters that shouldn't be replaced will be replaced with
--themselves.
--
--In order to avoid matching half of the "replace u with u"
--command as the replace part of another command, "uu" is placed
--at the beginning of the string. This ensures that only the
--2-character replacements for "w" get an extra "u".

cmdstring = "uua@b8c(d6e3f#g9h#i1i!jjk<l1limmnno0ppq9rrs5s$t+v>v<wuuw2ux%y?zz"


--Iterate over all the search/replace commands.
--The character to replace is in the "c" variable, the string to
--replace it with is in "r".
--
--Due to the dummy search/replace commands (i.e. "mm") placed
--in the string, this loop will also iterate over all letters
--of the alphabet.

for c,r in cmdstring:gmatch("(.)(.u?)") do
	
	--First, replace any occurences of the current letter
	--multiple times in a row with "<number><letter>".
	s = s:gsub(c..c.."+", function(p)
		return #p .. c
	end)
	
	--Then, replace the first occurence of the letter
	--with the replacement from the command string.
	s = s:gsub(c, r, 1)
end

print(s)
Jonathan S.
fuente
Lol lua :) buen trabajo
mdahmoune
2

C # (.NET Core), 317 , 289 , 279 bytes

p=>{string r="",l=r,h=r,c="a@b8c(d6e3f#g9h#i1i!k<l1lio0q9s5s$t+v>v<wuw2x%y?";int i=0,n=p.Length,d,a=1;for(;i<n;i++){h=p[i]+"";if(h==p[(i==n-1?i:i+1)]+""&&i!=n-1)a++;else{d=c.IndexOf(h);if(d>=0&&d%2<1){l=c[d+1]+"";h=l=="u"?"uu":l;c=c.Remove(d,2);}r+=a>1?a+""+h:h;a=1;}}return r;};

Pruébalo en línea!

Espero que esté bien recibir una matriz de caracteres como entrada y no como una cadena.

Sin golf :

string result = "", casesCharReplacement = result, currentChar = result, cases = "a@b8c(d6e3f#g9h#i1i!k<l1lio0q9s5s$t+v>v<wuw2x%y?";
int i = 0, n = pas.Length, casesIndex, charAmounts = 1;

// For every char in the pass.
for (; i < n; i++)
{
    currentChar = pas[i] + "";
    // if the next char is equal to the current and its not the end of the string then add a +1 to the repeated letter.
    if (currentChar == (pas[(i == n - 1 ? i : i + 1)] + "") && i != n - 1)
        charAmounts++;
    else
    {
        // Finished reading repeated chars (N+Char).
        casesIndex = cases.IndexOf(currentChar);
        // Look for the replacement character: only if the index is an even position, otherwise I could mess up with letters like 'i'.
        if (casesIndex >= 0 && casesIndex % 2 < 1)
        {
            casesCharReplacement = cases[casesIndex + 1]+"";
            // Add the **** +u
            currentChar = casesCharReplacement == "u"?"uu": casesCharReplacement;
            // Remove the 2 replacement characters (ex: a@) as I won't need them anymore.
            cases = cases.Remove(casesIndex, 2);
        }
        // if the amount of letters founded is =1 then only the letter, otherwise number and the letter already replaced with the cases.
        result += charAmounts > 1 ? charAmounts + ""+currentChar : currentChar;
        charAmounts = 1;
    }
}
return result;
Emiliano
fuente
1
Sí, está bien :) para la entrada
mdahmoune
2

C ++, 571 495 478 444 bytes

-127 bytes gracias a Zacharý

#include<string>
#define F r.find(
#define U(S,n)p=F s(S)+b[i]);if(p-size_t(-1)){b.replace(i,1,r.substr(p+n+1,F'/',n+p)-p-2));r.replace(p+1,F'/',p+1)-p,"");}
#define V(A)i<A.size();++i,c
using s=std::string;s m(s a){s b,r="/a@/b8/c(/d6/e3/f#/g9/h#/i1//i!/k</l1//li/o0/q9/s5//s$/t+/v>/wuu//w2u/x%/y?/";int c=1,i=0;for(;V(a)=1){for(;a[i]==a[i+1]&&1+V(a)++);b+=(c-1?std::to_string(c):"")+a[i];}for(i=0;V(b)){auto U("/",1)else{U("//",2)}}return b;}

la "/a@/b8/c(/d6/e3/f#/g9/h#/i1//i!/k</l1//li/o0/q9/s5//s$/t+/v>/wuu//w2u/x%/y?/"cadena se usa para transformar de un personaje a otro. 1 /significa que el primer "próximo carácter" debe ser reemplazado por lo que sigue al siguiente /, 2 significa que el segundo "próximo carácter" debe ser reemplazado por lo que sigue.

Pruébalo en línea

HatsuPointerKun
fuente
Genial, ¿podría agregar un enlace tio.run?
mdahmoune
@mdahmoune Se agrega el enlace TIO, con el código para probar sus casos de prueba :)
HatsuPointerKun
494 bytes , y actualice el enlace TIO en consecuencia si lo cambia.
Zacharý
@ Zacharý Debe colocar un espacio entre el nombre de la macro y el contenido de la macro, de lo contrario, arrojará un error al compilar con C ++ 17. Además, ¿sabe cómo eliminar un enlace TIO? (ya que el viejo es inútil)
HatsuPointerKun
1
444 bytes
Zacharý
2

R , 224 219 bytes

function(s,K=function(x)el(strsplit(x,"")),u=rle(K(s)))
Reduce(function(x,y)sub(K('abcdefghiiklloqsstvvwwxy')[y],c(K('@8(63#9#1!<1i095$+><'),'uu','2u',K('%?'))[y],x),1:24,paste0(gsub("1","",paste(u$l)),u$v,collapse=""))

Pruébalo en línea!

Desagradable, pero la parte principal es la sustitución iterativa en el Reduce. subcambia solo la primera aparición del partido.

¡Gracias a JayCe por señalar un buen golf!

Giuseppe
fuente
Buen trabajo :)))))
mdahmoune
ahorre 1 byte reorganizando args. No hace una gran diferencia, lo sé;)
JayCe
@ JayCe encontré algunos bytes más :-)
Giuseppe
1

Perl 5 , 123 bytes

Código de 122 bytes + 1 para -p.

Desarrollado independientemente de la respuesta de @ Xcali , pero usando un proceso muy similar.

s/(.)\1+/$&=~y!!!c.$1/ge;eval"s/$1/$2/"while'a@b8c(d6e3f#g9h#i1i!k<l1lio0q9s5t+v>v<x%y?'=~/(.)(.)/g;s/s/\$/;s/w/uu/;s;w;2u

Pruébalo en línea!

Dom Hastings
fuente
1

Python 2 , 220 216 194 190 188 bytes

import re
S=re.sub(r'(.)\1+',lambda m:`len(m.group(0))`+m.group(1),input())
for a,b in zip('abcdefghiiklloqsstvvxyww',list('@8(63#9#1!<1i095$+><%?')+['uu','2u']):S=S.replace(a,b,1)
print S

Pruébalo en línea!

Python 3 , 187 bytes

import re
S=re.sub(r'(.)\1+',lambda m:str(len(m.group(0)))+m.group(1),input())
for a,b in zip('abcdefghiiklloqsstvvxyww',[*'@8(63#9#1!<1i095$+><%?','uu','2u']):S=S.replace(a,b,1)
print(S)

Pruébalo en línea!

TFeld
fuente
Gracias Tfeld 192 bytes tio.run/…
mdahmoune
Gran golf;)
mdahmoune
186 bytes . También puede portar esto fácilmente a Python 3 en 192 bytes , pero no creo que deba ser una respuesta separada.
NieDzejkob
@NieDzejkob Parece que su versión de golf Python 2 produce una salida diferente a la versión actual del OP o su versión de Python 3.
Jonathan Frech
@JomathanFrech lo siento, como siempre prueba en producción. 188 bytes
NieDzejkob
1

Pip , 103102 bytes

aR:`(.)\1+`#_.B
Fm"abcdefghiiklloqsstvvwwxy"Z"@8(63#9#1!<1i095$+><WU%?"I#Ya@?@maRA:ym@1aR'W"uu"R'U"2u"

Pruébalo en línea!

Explicación

El código realiza tres pasos de transformación:

aR:`(.)\1+`#_.B  Process runs of identical letters

a                1st cmdline argument
 R:              Do this replacement and assign back to a:
   `(.)\1+`       This regex (matches 2 or more of same character in a row)
           #_.B   Replace with callback function: concatenate (length of full match) and
                  (first capture group)
                  Note: #_.B is a shortcut form for {#a.b}

Fm"..."Z"..."I#Ya@?@maRA:ym@1  Do the bulk of rules 2-25

  "..."                        String of letters to replace
       Z"..."                  Zip with string of characters to replace with
Fm                             For each m in the zipped list:
                   @m           First item of m is letter to replace
                a@?             Find its index in a, or nil if it isn't in a
               Y                Yank that into y
             I#                 If len of that is truthy:*
                     aRA:        Replace character in a at...
                         y        index y...
                          m@1     with second item of m

aR'W"uu"R'U"2u"  Clean up substitution
                 In the previous step, the replacements each had to be a single character.
                 This doesn't work for uu and 2u, so we use W and U instead (safe, since
                 uppercase letters won't be in the input) and replace them here with the
                 correct substitutions.
aR'W"uu"         In a, replace W with uu
        R'U"2u"  and U with 2u
                 and print the result (implicit)

* Necesitamos probar si a@?m@0es nulo. No es suficiente probar que es verdad, ya que 0 es un índice legítimo que es falso. Pip no tiene una forma interna breve de probar si un valor es nulo, pero probar su longitud funciona lo suficientemente bien en este caso: cualquier número tendrá una longitud de al menos 1 (verdadero), y cero tiene una longitud de cero (falsey).

DLosc
fuente