Hi everybody. I''m trying to convert a hex value into base64, but I''m having some problems. The problem is that Base64.encode64 is doing a conversion based on the string representation of the hex value (eg, I have a number represented in base 16 that I would like to be represented in base 64, to do the conversion mathematically, not based on the string representation of the base 16 number). It''s kind of a long story but basically I am hashing some data to create a password (eg, the hash IS the password, it''s not a hash of a password), and the hash is SHA1, so it''s a number represented by a 40 character string of hex. The problem is, I''d prefer a password that uses upper and lower case letters, not just 0-9, a-f. So converting this hex value into base64 will make the password shorter, but opens it up to many more possible letters. I''ve found that Bignum#to_s brings me close to what I want: Digest::SHA1.hexdigest(some text).hex.to_s(36) This changes eg, "60d06a02dc53d67b123647f12a0d896d5d839294", into "bb4f93cgwkckm9gl8g90n3zsp2zvwr8", which is a few chars shorter and is using 0-9, a-z instead of just 0-9, a-f, so it''s a step in the right direction. But it''d be really nice if I could do this: Digest::SHA1.hexdigest(some text).hex.to_s(64) to get a string that''s even shorter and using uppercase and lowercase letters as well as numbers, plus a couple symbols or whatever. Anybody have any ideas? The obvious: Base64.encode64("60d06a02dc53d67b123647f12a0d896d5d839294") just produces: NjBkMDZhMDJkYzUzZDY3YjEyMzY0N2YxMmEwZDg5NmQ1ZDgzOTI5NA= which is not what I''m looking for. encode64 just pukes if I feed it a Bignum as well. Thanks. -- Urban Artography http://artography.ath.cx
On May 4, 2005, at 11:59 PM, Rob Park wrote:> Hi everybody. I''m trying to convert a hex value into base64, but I''m > having some problems. The problem is that Base64.encode64 is doing a > conversion based on the string representation of the hex value[snip]> Anybody have any ideas? The obvious: > > Base64.encode64("60d06a02dc53d67b123647f12a0d896d5d839294")Is this really a single base-16 number? "60d06a02dc53d67b123647f12a0d896d5d839294".to_i( 16 ) #=> 552710903876121934266138116081162544013019157140 Or is it really a series of 40 bytes represented as hex pairs? "60d06a02dc53d67b123647f12a0d896d5d839294".scan( /../ ).each do |byte| puts byte.to_i( 16 ) end
On 5/5/05, Gavin Kistner <gavin-XtLdkLkwz3ZWk0Htik3J/w@public.gmane.org> wrote:> Is this really a single base-16 number? > "60d06a02dc53d67b123647f12a0d896d5d839294".to_i( 16 ) > #=> 552710903876121934266138116081162544013019157140 > > Or is it really a series of 40 bytes represented as hex pairs?It is an SHA1 hash, so to answer that question I''d have to know a lot more about what SHA1 is doing exactly when it hashes a file. I don''t think it''s relevant to the question though, because the ".hex.to_s(36)" is halfway to doing what I want it to do: it makes the string shorter, and it makes it use a-z instead of just a-f. I''m looking for some way to say ".to_s(64)" so that the string will be even shorter still, while using [0-9a-zA-Z]. ; irb irb(main):001:0> require ''digest/sha1'' => true irb(main):002:0> Digest::SHA1.hexdigest("foo") => "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" irb(main):003:0> Digest::SHA1.hexdigest("foo").hex => 68123873083688143418383284816464454849230703155 irb(main):007:0> Digest::SHA1.hexdigest("foo").hex.to_s(64) ArgumentError: illegal radix 64 from (irb):7:in `to_s'' from (irb):7 irb(main):008:0> Digest::SHA1.hexdigest("foo").hex.to_s(36) => "1e6gpc3ehk0mu2jqu8cg42g009s796b"> "60d06a02dc53d67b123647f12a0d896d5d839294".scan( /../ ).each do |byte| > puts byte.to_i( 16 ) > endWell, it''s not a very useful representation: Digest::SHA1.hexdigest("foo").scan(/../).each do |byte| print byte.hex.chr end prints mostly garbage. -- Urban Artography http://artography.ath.cx
Rob Park wrote:> This changes eg, "60d06a02dc53d67b123647f12a0d896d5d839294", into > "bb4f93cgwkckm9gl8g90n3zsp2zvwr8", which is a few chars shorter and is > using 0-9, a-z instead of just 0-9, a-f, so it''s a step in the right > direction. But it''d be really nice if I could do this: > > Digest::SHA1.hexdigest(some text).hex.to_s(64) > > to get a string that''s even shorter and using uppercase and lowercase > letters as well as numbers, plus a couple symbols or whatever. > > Anybody have any ideas? The obvious: > > Base64.encode64("60d06a02dc53d67b123647f12a0d896d5d839294") > > just produces: > > NjBkMDZhMDJkYzUzZDY3YjEyMzY0N2YxMmEwZDg5NmQ1ZDgzOTI5NA=> > which is not what I''m looking for. encode64 just pukes if I feed it a > Bignum as well.What about this? irb(main):001:0> Base64.encode64(Digest::SHA1.digest("foo")).chomp => "C+7Hteo/D9vJXQ3UfzxbwnXaijM=" irb(main):018:0> Digest::SHA1.hexdigest("foo").to_i(16).to_s(36) => "1e6gpc3ehk0mu2jqu8cg42g009s796b" irb(main):003:0> Digest::SHA1.hexdigest("foo") => "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"
On 5/5/05, Florian Groß <florgro-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> What about this? > > irb(main):001:0> Base64.encode64(Digest::SHA1.digest("foo")).chomp > => "C+7Hteo/D9vJXQ3UfzxbwnXaijM=" > irb(main):018:0> Digest::SHA1.hexdigest("foo").to_i(16).to_s(36) > => "1e6gpc3ehk0mu2jqu8cg42g009s796b" > irb(main):003:0> Digest::SHA1.hexdigest("foo") > => "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"Oh perfect, thanks. This is what I ended up doing: Base64.encode64(Digest::MD5.digest("foo")).gsub(/=+\n?/, "") (changed to md5 because it''s shorter, and added gsub because there''s really no reason for all the passwords to end with an equal sign and a newline ;) Thanks for your help! -- Urban Artography http://artography.ath.cx