Just thought I’d share this one to boost the available online information. Using String#crypt and man crypt you’ll come up with something similar to the gist below (extract from a project I’m busy working on).
module Linux
class User
class << self
# Generate an MD5 salt string
def salt
seeds = ('a'..'z').to_a
seeds.concat( ('A'..'Z').to_a )
seeds.concat( (..9).to_a )
seeds.concat ['/', '.']
seeds.compact!
salt_string = '$1$'
8.times { salt_string << seeds[ rand(seeds.size) ].to_s }
salt_string
end
# Crypt a password suitable for use in shadow files
def crypt( string )
string.crypt( self.salt )
end
end
end
end
And the spec
require File.dirname(__FILE__) + '/../spec_helper'
describe Linux::User do
describe "generating shadow passwords" do
it "should generate a salt for crypt" do
salt = Linux::User.salt
salt.length.should be(11)
salt.should match(/^\$1\$[a-zA-Z0-9\.\/]{8}$/)
end
it "should generate a shadow password" do
pass = Linux::User.crypt( 'secret' )
pass.should match(/^\$1\$[a-zA-Z0-9\.\/]{8}\$[a-zA-Z0-9\.\/]{22}$/)
pass.length.should be(34)
end
end
end
HTH