ucenter authcode加解密算法for ruby.authcode.rb
感谢ice同学提供源码(https://github.com/iceskysl)
[ruby]
#coding: utf-8
require ‘digest/md5’
require ‘base64’
require ‘cgi’
class Authcode
def authcode(auth_key, string, operation = ”, expiry = 0)
ckey_length = 4
key = md5(auth_key)
keya = md5(key[0, 16])
keyb = md5(key[16, 16])
keyc = ckey_length > 0 ? (operation == ‘DECODE’ ? string[0, ckey_length] : (md5(microtime()))[-ckey_length..-1]) : ”
cryptkey = keya + md5(keya+keyc)
key_length = cryptkey.size
string = operation == ‘DECODE’ ? base64_url_decode(string[ckey_length..-1]) : sprintf(‘%010d’, expiry>0 ? expiry + Time.now.to_i : 0)+ (md5(string+keyb))[0, 16] + string
string_ords = ords(string)
string_length = string_ords.size
result = ”
box = (0..255).to_a
rndkey = []
0.upto(255) do |i|
rndkey[i] = (cryptkey[i % key_length]).ord
end
j = i = 0
while i < 256 do
j = (j + box[i] + rndkey[i]) % 256
box[i], box[j] = box[j], box[i]
i +=1
end
a = j = i = 0
while i < string_length
a = (a + 1) % 256
j = (j + box[a]) % 256
box[a], box[j] = box[j], box[a]
result += (string_ords[i] ^ (box[(box[a] + box[j]) % 256])).chr
i +=1
end
if operation == ‘DECODE’ then
if ( result[0,10] == ‘0’*10 || (result[0, 10]).to_i – Time.now.to_i > 0 ) and
result[10, 16] == (md5(result[26..-1] + keyb))[0, 16] then
return result[26..-1]
else
return ”
end
else
keyc + (Base64.encode64(result)).gsub(/=/, ”)
end
end
def md5(s)
Digest::MD5.hexdigest(s)
end
def base64_url_decode(str)
str += ‘=’ * (4 – str.length.modulo(4))
Base64.decode64(str.tr(‘-_’,’+/’))
end
def microtime
epoch_mirco = Time.now.to_f
epoch_full = Time.now.to_i
epoch_fraction = epoch_mirco – epoch_full
epoch_fraction.to_s + ‘ ‘ + epoch_full.to_s
end
def ords(s)
s.bytes.to_a
end
end
# 测试代码,和discuz的调用方法并不完全相同,第一个参数是加密解密算子,第二个才是字符串值
# code = "b384r5HiERJ+kEbb25t9jbtDXULGnCnR++1EK9xlmG74OKkd3hfjC4+dUJePocsJHts2JeO4/Po"
# key = "Y426x6Basctda9f94e49h3B6OeofcdX0J8Ua2a37P1M9Jd00he28o3t5ocq707U5"
# y = (Authcode.new).authcode(key,code,’DECODE’)
# puts " —– #{y}"
# #action=synlogin&username=homey0&uid=713627&password=10c308db89f5cf6bd6d011de005c25d2&time=1344610064
[/ruby]