Sicurezza di Post-It


16

Come forse saprai, gli hacker sono ovunque e vogliono hackerare tutto. Ti è stato chiesto di imporre requisiti di password che fermeranno qualsiasi hacker . Il problema è che il tuo capo ha sentito che pagare per LOC è malefico e ti paga $ 1800 - $ 0,03 * caratteri inseriti al mese per farti scrivere cose più semplici che potrebbero funzionare. Quindi, devi usare un piccolo numero di caratteri (si spera molto piccolo), o altrimenti dimenticare i soldi. Inoltre, al tuo capo non importa quale lingua utilizzerai.

I requisiti per le password valide sono simili a quelli indicati nell'articolo citato, ad eccezione dei requisiti basati sul dizionario che sono stati rimossi per evitare che la soluzione dipenda da file esterni, non è necessario verificare la corrispondenza delle lettere (difficile capire cosa significhi effettivamente), l'ultima regola viene rimossa (cos'è 3/4?) e non controlla le vecchie password.

I requisiti esatti dopo aver rimosso alcuni requisiti dall'articolo collegato sono:

  • avere almeno 8 carattere / i!
  • non deve superare i 12 caratteri!
  • hanno caratteri maiuscoli e minuscoli!
  • non hanno più di 8 lettere maiuscole!
  • non hanno più di 8 lettere minuscole!
  • avere almeno 2 lettere!
  • avere una lettera principale!
  • avere almeno 1 cifra / e!
  • non essere il tuo nome utente!
  • non essere il tuo nome utente al contrario!
  • non contiene il tuo nome utente!
  • non contenere il tuo nome utente al contrario!
  • non avere più di 1 coppia (e) di personaggi ricorrenti!
  • non avere 3 ricorrenze dello stesso personaggio!
  • non contenere carati (^)
  • non contenere spazio
  • non contenere =
  • non conatain &
  • non contenere #
  • non contenere,
  • non conatain ;
  • non contenere "
  • non contenere>
  • non contenere <
  • non contenere [
  • non contenere |
  • non contenere)

Tutti gli errori di ortografia in questo elenco sono stati lasciati così come sono.

$ ./checkpass
Username: John
Password: L!]E2m69
OK.

$ ./checkpass
Username: John
Password: JohnnhoJ12
Nope.

$ ./checkpass
Username: JOE.smith
Password: JOE!smith123
OK.

Il codice più corto vince denaro (inviato come file JPG). Deve mostrare "Username:" e "Password:" richiede e rispondere con un messaggio esatto.


1
Bello, vedere una sfida di golf nel codice in un articolo del Daily WTF, +1 ;-)
ChristopheD

1
Il primo esempio dovrebbe fallire ("avere caratteri maiuscoli e minuscoli!"), No?
Howard,

@Howard: significa che nella password sono necessarie sia lettere maiuscole che minuscole. Notare la mancanza della parola "non".
Konrad Borowski il

Non è molto ovvio in alcuni caratteri che la l in quella prima password è una lettera minuscola e non il numero uno, quindi sto modificando per sostituirla con una lettera inequivocabile minuscola.
Peter Taylor,

@PeterTaylor Ah, grazie. In effetti l'ho letto come 1(cifra uno) invece di ell.
Howard,

Risposte:


8

Perl, 203 194 189 193 caratteri

Ecco la mia opinione del Perl sul problema:

print"Username: ";chop($u=<>);$n=reverse$u;print"Password: ";$_=<>;
say/^\pL.{7,11}$/*/\d/*/[A-Z]/*9>y/A-Z//&y/a-z//<9*/[a-z]/*
!/[" #,;->^&[|)]|(.)(.*\1.*\1|\1.*(.)\3)|\Q$u\E|\Q$n/?"OK.":"Nope."

Le regex verificano, nell'ordine, che la password:

  • inizia con una lettera, ha 8-12 caratteri

  • contiene una cifra

  • contiene una lettera maiuscola

  • ha otto o meno lettere maiuscole

  • ha otto o meno lettere minuscole

  • contiene una lettera minuscola

  • non contiene nessuno dei segni di punteggiatura vietati, tre occorrenze di qualsiasi carattere, più di una ricorrenza di un carattere raddoppiato, il nome utente o il nome utente invertiti.

(Grazie a Peter Taylor per aver segnalato un bug nella versione 189-char.)


Ho capito come eseguirlo su ideone use v5.10;e fallisce il mio caso di prova "I regex sono fuggiti correttamente". Vedi ideone.com/QKFnZ
Peter Taylor,

@PeterTaylor: Non conosco Ruby, ma nella correzione Perl sarebbe \Q$u\E|\Q$n(l'ultimo \Epuò essere saltato, se questa parte viene spostata alla fine).
Konrad Borowski il

OTOH Penso che un personaggio possa essere salvato unendo le ripetizioni come (.)(.*\1.*\1|\1.*(.)\3)(non testato - non proverò a scrivere una batteria di prova completa con ideone).
Peter Taylor,

5

Rubino, 270 caratteri

$><<"Username: ";u=gets.chop
$><<"Password: ";gets
puts ('^.{8,12}$+\p{Lower}+\p{Upper}+^(\p{Alpha}.*){2}+\d+(\p{Lower}.*){9}+(\p{Upper}.*){9}+(.)\1.*(.)\2+(.).*\1.*\1+[ ^=&#,;"<>\[|)]+'+u+?++u.reverse).split(?+).map{|r|/#{r}/=~$_??A:?B}*""=="AAAAABBBBBBB"?"OK.":"Nope."

Un'implementazione rubino si basa su dodici espressioni regolari. Ogni espressione è una corrispondenza positiva (prime cinque) o negativa (ultime sette). Come limitazione, il nome utente può contenere solo lettere o cifre.

Corrispondenze di espressioni regolari positive:

  • /^.{8,12}$/: avere almeno 8 carattere / i!, non essere più lungo di 12 caratteri!
  • /\p{Lower}/e /\p{Upper}/: avere caratteri maiuscoli e minuscoli!
  • /^(\p{Alpha}.*){2}/: avere almeno 2 lettera / e !, avere una lettera iniziale!
  • /\d/: avere almeno 1 cifra / e!

Corrispondenze di espressioni regolari negative:

  • /(\p{Lower}.*){9}/: non avere più di 8 lettere minuscole!
  • /(\p{Upper}.*){9}/: non avere più di 8 lettere maiuscole!
  • /(.)\1.*(.)\2/: non avere più di 1 coppia (e) di personaggi ricorrenti!
  • /(.).*\1.*\1/: non avere 3 ricorrenze dello stesso personaggio!
  • /[ ^=&#,;"<>\[|)]/: non contiene il cursore, spazio, =, &, #, ,,;, ",>, <, [, |,)
  • /#{u}/: non essere il tuo nome utente !, non contenere il tuo nome utente!
  • /#{u.reverse}/: non essere il tuo nome utente al contrario !, non contenere il tuo nome utente al contrario!

Questo non sfugge al nome utente, quindi una password perfettamente valida può essere rifiutata. Test case su ideone.com/bPpeo
Peter Taylor,

@PeterTaylor Ecco perché ho notato la limitazione per i nomi utente nella mia risposta.
Howard,

1

Python 3, 291 byte / caratteri

from re import*
n,p=map(input,["Username: ","Password: "])
c,U,L=lambda x:len(split("[%s]"%x,p)),"A-Z","a-z"
print(["OK.","Nope."][any([8>len(p)>12,2>c(U)>9,2>c(L)>9,3>c(U+L),match(U+L,p),2>c("0-9"),n in p,n[::-1]in p,any(c(x)>3 for x in p),len(findall("(.)\\1",p))>1,c(' ^=&#,;"><[|)')>1])])

Più ben formattato e commentato:

# import all elements from the regular expression module
from re import *

# Get the two lines of user input (username `n`, password `p`):
n, p = map(input, ["Username: ","Password: "])

# Assign some internally useful shortcuts (uppercase letters `U`, lowercase letters `L`):
# `c(x)` counts the occurrences of pattern `x` in the password `p` plus 1
c, U, L = lambda x: len(split("[%s]" % x, p)), "A-Z", "a-z"

# Print the test result: `"OK."` if the `any(...)` function returned `False`, else `"Nope."`.
# The `any(...)` combines the result of all enclosed checks and returns `True` if at least
# one of the checks failed (returned `True`).
print(["OK.", "Nope."][any([                                # vvv--- CHECKS: ---vvv
                             8>len(p)>12,                   # password length 8-12
                             2>c(U)>9,                      # 1-8 uppercase letters
                             2>c(L)>9,                      # 1-8 lowercase letters
                             3>c(U+L),                      # at least 2 letters
                             match(U+L,p),                  # starts with a letter
                             2>c("0-9"),                    # at least 1 digit
                             n in p,                        # username is not (in) the pw.
                             n[::-1]in p,                   # reversed name not (in) the pw.
                             any(c(x)>3 for x in p),        # at most 3 same characters
                             len(findall("(.)\\1",p))>1,    # at most 1 pair (e.g. "AA")
                             c(' ^=&#,;"><[|)')>1])         # does not contain special char.
                           ])

Puoi trovare questa soluzione su ideone.com , ma l'output sembra un po 'brutto perché non mostra l'input predefinito o anche le interruzioni di riga lì. Inoltre, la combinazione nome utente-password "JOE.smith"- "JOE!smith123"è attualmente inserita come dati di input fissi.
Ho aggiunto una ripartizione di tutti i controlli come output di debug però.

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.