2016-03-27 20 views
-3

我的任務是使用一個非常簡單的密碼驗證方案,但對於我的生活,我似乎無法得到這個權利。這是任務:如何驗證字符串中的連續數字不是順序的?

用戶通過表單發送6個字符的數字密碼。在 爲了強制使用安全密碼,請創建一個確認號碼 不能連續向上或向下。

以下是我有:

password = '246879' 
new_password = password.split('').map { |s| s.to_i } 

new_password.each_with_index do |val, index| 

    next_element = new_password[index + 1] 
    prev_element = new_password[index - 1] 

    if new_password[index] + 1 == next_element 
    puts 'next bad' 
    break 
    elsif 
    new_password[index] - 1 == prev_element 
    puts 'prev bad' 
    break 
    end 
end 

的密碼失效的87,因爲7是一個小於8

回答

3

我喜歡CodeGnome的回答,但我會簡化一下。

def valid_password?(password) 
    password.chars.each_cons(2).none? do |a, b| 
    (a.ord - b.ord).abs == 1 
    end 
end 

p valid_password?('246879') 
#=> false 

p valid_password?('246809') 
#=> true 

這假定所有的字符都是數字(即其他代碼驗證了這一點)。由於"0""9"按照UTF-8的順序排列(如ASCII),所以我們不需要將它們轉換爲數字,我們只需要比較它們的字符代碼。它也使用Enumerable#none?,因爲這類問題正是它的原因。

+0

你的答案絕對比我的更緊湊,所以+1。我儘量避免使用巧妙的代碼來支持顯式,但我真的很喜歡這個答案返回表達式本身的值,而不是依靠分支來返回布爾值。 –

0

使用Enumerable#each_cons比較字符或整數的滑動窗口。例如:

def valid_password? str_of_ints 
    str_of_ints.chars.map(&:to_i).each_cons(2) do |i, j| 
    return false if i.succ == j or i.pred == j 
    end 
    true 
end 

valid_password? '246879' 
#=> false 

valid_password? '246809' 
#=> true 
相關問題