Şifre gücünü doğrulamak için normal ifade


142

Şifre gücü kriterlerim aşağıdaki gibidir:

  • 8 karakter uzunluk
  • Büyük Harf'de 2 harf
  • 1 Özel Karakter (!@#$&*)
  • 2 rakam (0-9)
  • Küçük Harfle 3 harf

Birisi bana aynı şekilde regex verebilir mi? Tüm koşullar şifre ile karşılanmalıdır.


2
Parola güvenliği önlemlerinizin genel olarak Internet'e güvenmeye gerçekten istekli misiniz?
Borealid

12
@Borealid: parola ilkelerini yayıncılık genellikle gerektiğini değil önemli ölçüde güvenliğinizi etkiler. Varsa, politikalarınız kötüdür ("Yalnızca passwordve hello123geçerli şifrelerdir!").
Joachim Sauer

3
@Joachim Sauer: Demek istediğim bu değildi. Demek istediğim, posterin muhtemelen aldığı regex'e güveneceği idi. İyi bir fikir değil.
Borealid

3
Aslında bu normal ifade servis kodunda olacak, ben körü körüne güven değil diff vakaları için test olacak :)
Ajay Kelkar

9
Karmaşık parola kuralları genellikle daha güvenli parolalara yol açmaz, önemli olan yalnızca minimum uzunluktur. İnsanlar tonlarca güçlü şifreyi hatırlayamazlar ve bu tür kurallar iyi şifre düzenlerine müdahale edebilir. İnsanlar, örneğin "Şifre-2014" gibi zayıf şifreler kullanarak bu kuralları atlamak için çok yaratıcı olabilirler. Genellikle daha güçlü şifreler yerine daha zayıf şifreler elde edersiniz.
martinstoeckli

Yanıtlar:


428

Bu kontrolleri olumlu ileriye dönük iddialarla yapabilirsiniz:

^(?=.*[A-Z].*[A-Z])(?=.*[!@#$&*])(?=.*[0-9].*[0-9])(?=.*[a-z].*[a-z].*[a-z]).{8}$

Rubular bağlantı

Açıklama:

^                         Start anchor
(?=.*[A-Z].*[A-Z])        Ensure string has two uppercase letters.
(?=.*[!@#$&*])            Ensure string has one special case letter.
(?=.*[0-9].*[0-9])        Ensure string has two digits.
(?=.*[a-z].*[a-z].*[a-z]) Ensure string has three lowercase letters.
.{8}                      Ensure string is of length 8.
$                         End anchor.

92
En az uzunluk isteyen herkes içinn.{8}.{n,}
NullUserException

14
Tam açıklama için +1. Şifre kurallarım farklı ama cevabınıza göre normal ifadeyi uyarlayabilirim.
Morvael

14
Normal ifadede neler olduğunu açıkladığınız için teşekkür ederiz. Bu, sözdizimine hiç girmemiş olanlar için harika bir öğrenme örneği olarak hizmet eder.

4
Ayrıca normal ifadenin açıklamasını da takdir ediyorum. Çoğu zaman neler olduğunu gerçekten anlamadan bulduğum karmaşık düzenli ifadeyi kullanıyorum.
Nicholas Smith

4
Harika desen, merak ediyorum neden niceleyiciler kullanmıyorsunuz? En az 1 özel, 1 sayı, 1 özel karakter, 8 karakter: ^ (? =. * ([AZ]) {1,}) (? =. * [! @ # $ & *] {1,}) ( ? =. * [0-9] {1,}) (? =. * [Az] {1,}). {8,100} $
RockOnGom

11

Kısıtlamalarınızın her birini ayrı ayrı belirtmek için sıfır uzunlukta pozitif görünüm başlıkları kullanabilirsiniz:

(?=.{8,})(?=.*\p{Lu}.*\p{Lu})(?=.*[!@#$&*])(?=.*[0-9])(?=.*\p{Ll}.*\p{Ll})

Desteklemiyorsa regex motoru ise \pgösterim ve saf ASCII yeterlidir, o zaman değiştirebilir \p{Lu}ile [A-Z]ve \p{Ll}ile [a-z].


8

Yukarıda verilen cevaplar mükemmel ancak büyük bir cevap yerine birden çok daha küçük normal ifadeyi kullanmanızı öneririm .
Uzun regex'i bölmenin bazı avantajları vardır:

  • yazma ve okuma kolaylığı
  • hata ayıklama kolaylığı
  • normal ifadenin bir kısmını ekleme / kaldırma kolaylığı

Genellikle bu yaklaşım, kodu kolayca korunabilir kılar .

Bunu söyledikten sonra, Swift içinde yazdığım bir kod parçası paylaşıyorum :

struct RegExp {

    /**
     Check password complexity

     - parameter password:         password to test
     - parameter length:           password min length
     - parameter patternsToEscape: patterns that password must not contains
     - parameter caseSensitivty:   specify if password must conforms case sensitivity or not
     - parameter numericDigits:    specify if password must conforms contains numeric digits or not

     - returns: boolean that describes if password is valid or not
     */
    static func checkPasswordComplexity(password password: String, length: Int, patternsToEscape: [String], caseSensitivty: Bool, numericDigits: Bool) -> Bool {
        if (password.length < length) {
            return false
        }
        if caseSensitivty {
            let hasUpperCase = RegExp.matchesForRegexInText("[A-Z]", text: password).count > 0
            if !hasUpperCase {
                return false
            }
            let hasLowerCase = RegExp.matchesForRegexInText("[a-z]", text: password).count > 0
            if !hasLowerCase {
                return false
            }
        }
        if numericDigits {
            let hasNumbers = RegExp.matchesForRegexInText("\\d", text: password).count > 0
            if !hasNumbers {
                return false
            }
        }
        if patternsToEscape.count > 0 {
            let passwordLowerCase = password.lowercaseString
            for pattern in patternsToEscape {
                let hasMatchesWithPattern = RegExp.matchesForRegexInText(pattern, text: passwordLowerCase).count > 0
                if hasMatchesWithPattern {
                    return false
                }
            }
        }
        return true
    }

    static func matchesForRegexInText(regex: String, text: String) -> [String] {
        do {
            let regex = try NSRegularExpression(pattern: regex, options: [])
            let nsString = text as NSString
            let results = regex.matchesInString(text,
                options: [], range: NSMakeRange(0, nsString.length))
            return results.map { nsString.substringWithRange($0.range)}
        } catch let error as NSError {
            print("invalid regex: \(error.localizedDescription)")
            return []
        }
    }
}

Ayrıca, yukarıdaki gibi karmaşık regex kullanırken, kendinizi felaketli geri izlemeye ( normal-expressions.info/catastrophic.html ) açmak çok kolaydır . Bir kullanıcı "garip" bir parola kullandığı için, sunucunuz% 100 CPU ile kilitlenene kadar bir güne kadar fark edilmeyebilir. Örnek: ^ ([a-z0-9] +) {8,} $ (hatayı görebiliyor musunuz?)
aKzenT

5

Eklemeyi öneririm

(?!.*pass|.*word|.*1234|.*qwer|.*asdf) exclude common passwords

1

codaddict'in çözümü iyi çalışıyor, ancak bu biraz daha verimli: (Python sözdizimi)

password = re.compile(r"""(?#!py password Rev:20160831_2100)
    # Validate password: 2 upper, 1 special, 2 digit, 1 lower, 8 chars.
    ^                        # Anchor to start of string.
    (?=(?:[^A-Z]*[A-Z]){2})  # At least two uppercase.
    (?=[^!@#$&*]*[!@#$&*])   # At least one "special".
    (?=(?:[^0-9]*[0-9]){2})  # At least two digit.
    .{8,}                    # Password length is 8 or more.
    $                        # Anchor to end of string.
    """, re.VERBOSE)

Reddedilen karakter sınıfları, sıfır geri izleme gerektiren tek bir adımda istenen karaktere kadar her şeyi tüketir. (Nokta yıldız çözümü gayet iyi çalışıyor, ancak biraz geri izleme gerektiriyor.) Tabii ki şifreler gibi kısa hedef dizeleriyle, bu verimlilik artışı ihmal edilebilir.


Lütfen doğru olup olmadığını kontrol eder misiniz? Üçlü çift tırnak ve soru işareti arasındaki ilk satırdaki yuvarlak köşeli ayraç açtığından şüpheliyim. Python yorumunun (karma) sonra olduğunu görebiliyorum. Son çapa (dolar işareti) yakın muhabir kapanış yuvarlak köşeli ayraç göremiyorum. Ben bir regex profy değilim belirtmek gerekir.
lospejos

@lospejos - # normal bir satırlık yorumun başlangıcı değil. Bu karma, a ile başlayan ve a ile biten bir yorum grubunun parçasıdır . Bu normal ifadede dengesiz parens yok. (?#)
ridgerunner

1
import re

RegexLength=re.compile(r'^\S{8,}$')
RegexDigit=re.compile(r'\d')
RegexLower=re.compile(r'[a-z]')
RegexUpper=re.compile(r'[A-Z]')


def IsStrongPW(password):
    if RegexLength.search(password) == None or RegexDigit.search(password) == None or RegexUpper.search(password) == None or RegexLower.search(password) == None:
        return False
    else:
        return True

while True:
    userpw=input("please input your passord to check: \n")
    if userpw == "exit":
        break
    else:
        print(IsStrongPW(userpw))

1

@ codaddict'in çözümü işe yarayacak.

Ayrıca, bazı kurallarınızı şu şekilde değiştirmeyi de düşünmelisiniz:

  1. %, ^, (,), -, _, + ve nokta gibi başka özel karakterler ekleyin. ABD klavyelerindeki sayı işaretlerinin üstünde kaçırdığınız tüm özel karakterleri ekliyorum. Normal ifade kullandığı olanlar kaçmak.
  2. Şifreyi 8 veya daha fazla karakter yapın. Sadece statik bir sayı 8 değil.

Yukarıdaki iyileştirmelerle, daha fazla esneklik ve okunabilirlik için normal ifadeyi değiştireceğim.

^(?=.*[a-z]){3,}(?=.*[A-Z]){2,}(?=.*[0-9]){2,}(?=.*[!@#$%^&*()--__+.]){1,}.{8,}$

Temel Açıklama

(?=.*RULE){MIN_OCCURANCES,}     Each rule block is shown by (){}. The rule and number of occurrences can then be easily specified and tested separately, before getting combined

Detaylı açıklama

^                             start anchor
(?=.*[a-z]){3,}               lowercase letters. {3,} indicates that you want 3 of this group
(?=.*[A-Z]){2,}               uppercase letters. {2,} indicates that you want 2 of this group
(?=.*[0-9]){2,}               numbers. {2,} indicates that you want 2 of this group
(?=.*[!@#$%^&*()--__+.]){1,}   all the special characters in the [] fields. The ones used by regex are escaped by using the \ or the character itself. {1,} is redundant, but good practice, in case you change that to more than 1 in the future. Also keeps all the groups consistent
{8,}                          indicates that you want 8 or more
$                             end anchor

Son olarak, burada test amaçlı olarak yukarıdaki normal ifadeye sahip bir robulink


@AFract'a teşekkürler. Kodumda kullanıyorum. Okunabilirliği ve tekrarlama yeteneğini seviyorum, çünkü geri dönüp gelecekte değiştirmek istediğinizde, örneğin bir şifre politikası değişikliği durumunda :)
lsu_guy

0

PHP için bu iyi çalışıyor!

 if(preg_match("/^(?=(?:[^A-Z]*[A-Z]){2})(?=(?:[^0-9]*[0-9]){2}).{8,}$/", 
 'CaSu4Li8')){
    return true;
 }else{
    return fasle;
 }

bu durumda sonuç doğrudur

Thsks @ridgerunner için


neden olmasın return preg_match("/^(?=(?:[^A-Z]*[A-Z]){2})(?=(?:[^0-9]*[0-9]){2}).{8,}$/", 'CaSu4Li8')?
aloisdg taşınma codidact.com

0

Başka bir çözüm:

import re

passwordRegex = re.compile(r'''(
    ^(?=.*[A-Z].*[A-Z])                # at least two capital letters
    (?=.*[!@#$&*])                     # at least one of these special c-er
    (?=.*[0-9].*[0-9])                 # at least two numeric digits
    (?=.*[a-z].*[a-z].*[a-z])          # at least three lower case letters
    .{8,}                              # at least 8 total digits
    $
    )''', re.VERBOSE)

def userInputPasswordCheck():
    print('Enter a potential password:')
    while True:
        m = input()
        mo = passwordRegex.search(m) 
        if (not mo):
           print('''
Your password should have at least one special charachter,
two digits, two uppercase and three lowercase charachter. Length: 8+ ch-ers.

Enter another password:''')          
        else:
           print('Password is strong')
           return
userInputPasswordCheck()

0

Parola aşağıdaki 4 karmaşıklık kuralından en az 3 tanesini karşılamalıdır,

[en az 1 büyük harf (AZ) en az 1 küçük harf (az) en az 1 basamak (0-9) en az 1 özel karakter - boşluğa özel karakterler olarak davranmayı unutmayın]

en az 10 karakter

en fazla 128 karakter

art arda en fazla 2 özdeş karakter (ör. 111 kullanılamaz)

'^ (?!. (.) \ 1 {2}) ((? =. [Az]) (? =. [AZ]) (? =. [0-9]) | (? =. [Az] ) (? =. [AZ]) (? =. [^ A-zA-Z0-9]) | (? =. [AZ]) (? =. [0-9]) (? =. [^ A -zA-Z0-9]) | (? =. [az]) (? =. [0-9]) (? =. * [^ a-zA-Z0-9])). {10,127} $ '

(?!. * (.) \ 1 {2})

(? =. [az]) (? =. [AZ]) (? =. * [0-9])

(? =. [az]) (? =. [AZ]) (? =. * [^ a-zA-Z0-9])

(? =. [AZ]) (? =. [0-9]) (? =. * [^ A-zA-Z0-9])

(? =. [az]) (? =. [0-9]) (? =. * [^ a-zA-Z0-9])

. {10,127}


0

Yukarıdaki regex maalesef benim için işe yaramadı. Güçlü bir parolanın temel kuralları

  • En az büyük harf içermelidir
  • En az küçük bir harf içermelidir
  • En az bir sayı içermelidir
  • En az özel bir karakter içermelidir
  • Ve minimum uzunluk

Yani, En İyi Regex

^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\$%\^&\*]).{8,}$

Yukarıdaki normal ifadenin minimum uzunluğu 8'dir. {8,} yerine { any_number ,} olarak değiştirebilirsiniz.

Kurallarda değişiklik?

diyelim ki en az x karakter küçük harf, y karakter büyük harf, z karakter sayı, Toplam minimum uzunluk w . Sonra aşağıda normal ifadeyi deneyin

^(?=.*[a-z]{x,})(?=.*[A-Z]{y,})(?=.*[0-9]{z,})(?=.*[!@#\$%\^&\*]).{w,}$

Not: Normal ifadede x , y , z , w değerini değiştir

Düzenleme: Güncellenmiş normal yanıt

Edit2: Ekleme değişikliği


Normal ifadeniz eşleşiyor Güçlü bir şifre 12345678olduğundan emin misiniz ? Lütfen göndermeden önce normal ifadenizi deneyin.
Toto

Bu daha iyi ama soruyu cevaplamıyor, 1) 8 karakter uzunluk istiyorlar. 2) Büyük Harf 2 harf. 3) 1 Özel Karakter (! @ # $ & *). 4) 2 rakam (0-9). 5) 3 Harf Küçük Harf.
Toto

@Toto Düşüncelerinizi şimdi paylaşır mısınız?
Juned Khatri

Normal ifadeniz, 2 zorunlu Büyük Harf'in diğer karakterlerle ayrılabileceğini dikkate almaz; küçük harf ve rakamlar için aynı nottur. Geçerli cevap kabul edilen cevaptır.
Toto
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.