关于DZ的Authcode函数转JS版的问题。 本帖最后由 TottyAndBaty 于 2013-08-30 23:43:38 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 js 代码部分68 strbuf[i] =chr(ord(strbuf[i]) ^ (box[(box[a] + box[j]) % 256]))这个 strbuf 是数组吗?无论从21 strbuf = Base64.decode(str);还是36 strbuf = str;上看,strbuf 都是字符串那么 strbuf[i] = 'x' 这样写是无效的,虽然不报错同样 ord(strbuf[i]) 也是不能返回正确值的对应 ord(strbuf[i]) 的 js 是strbuf.charCodeAt(i)对应 chr(n) 的 js 是String.fromCharCode(n)没有认真去看你提供的php同名函数,但至少你的 js 取值、赋值部分已经就出问题了另外:DZ 的发行版是分 utf-8 和 gbk 的由于字符内码的原因,utf-8 版中的 Authcode 编码结果是不能在 gbk 版中正确解码的(解出的还是utf-8的)当然如果不含有中文是没有问题的,这一点你在测试的时候一定要注意那个 Base64 类也是针对 utf-8 编码的。如果 php 端不是 utf-8 的,你也不能得到相同的结果 不好意思,疏忽了。发错了版本。这段代码是我最后修正的结果: function authcode(str, operation, key, expiry) { var operation = operation ? operation : 'DECODE'; var key = key ? key : ''; var expiry = expiry ? expiry : 0; var ckey_length = 4; key = md5(key); // 密匙a会参与加解密 var keya = md5(key.substr(0, 16)); // 密匙b会用来做数据完整性验证 var keyb = md5(key.substr(16, 16)); // 密匙c用于变化生成的密文 var keyc = ckey_length ? (operation == 'DECODE' ? str.substr(0, ckey_length): md5(microtime()).substr(-ckey_length)) : ''; // 参与运算的密匙 var cryptkey = keya+md5(keya+keyc); var string=""; if(operation == 'DECODE') { string =Base64.decode(str.substr(ckey_length)); } else { expiry = expiry ? expiry + time() : 0; tmpstr = expiry.toString(); if(tmpstr.length>=10) string = tmpstr.substr(0,10)+md5(str+keyb).substr(0, 16)+str; else { var count = 10 - tmpstr.length; for(var i=0;i<count;i++) { tmpstr = '0'+tmpstr; } string = tmpstr+md5(str+keyb).substr(0, 16)+str; } } var box = new Array(256); for(var i=0; i < 256; i++) { box[i] = i; } var rndkey = new Array(); // 产生密匙簿 for(var i=0; i < 256; i++) { rndkey[i] = cryptkey.charCodeAt(i % cryptkey.length); } // 用固定的算法,打乱密匙簿,增加随机性,好像很复杂,实际上对并不会增加密文的强度 for(var j = i = 0; i < 256; i++) { j = (j + box[i] + rndkey[i]) % 256; tmp = box[i]; box[i] = box[j]; box[j] = tmp; } // 核心加解密部分 var result = ''; for(var a = j = i = 0; i < string.length; i++) { a = (a + 1) % 256; j = (j + box[a]) % 256; tmp = box[a]; box[a] = box[j]; box[j] = tmp; result+=String.fromCharCode(string.charCodeAt(i) ^ (box[(box[a] + box[j]) % 256])); } if(operation == 'DECODE') { var s=""; if((result.substr(0, 10) == 0 || result.substr( 0, 10) - time() > 0) && result.substr(10, 16) == md5(result.substr(26)+keyb).substr(0, 16)) { s = result.substr(26); } } else { var s = Base64.encode(result); var regex = new RegExp('=', "g"); s = s.replace(regex, ''); s = keyc+s; } return s;}这里基本上没采用替代版的CHR,ORD,等,都用的JS只带的。我的测试页面编码都是UTF-8编码。这里的Base64.encode与php的base64_encode结果一样。前文说的ord,chr 都有提供JS版本的。chr:http://phpjs.org/functions/chr/ord:http://phpjs.org/functions/ord/ 原本放在源码的加密解密数据,你现在用JS来实现,那么问一下,密匙你准备怎么处理?直接放在JS里么? SMTP邮件操作类 发有邮件 中文内容是乱码 想转行做PHP了 如何判断字符串中值的类型并将其转换成对应变量类型 例'12.1','10', 'string'->12.1,10,'string' 正则表达式的一个问题 email的判断 几个小问题,急,只好请教各位了 php session 问题 请大家帮忙------------系统 Mandrake10.1 问一个问题,不知道能不能实现,请各位帮忙看看,谢谢~~~ 用text做数据库,怎么分页?! 请大家讨论一下php的发展前景? php替换的问题 请问百度编辑器怎么用啊?
68 strbuf[i] =chr(ord(strbuf[i]) ^ (box[(box[a] + box[j]) % 256]))
这个 strbuf 是数组吗?
无论从
21 strbuf = Base64.decode(str);
还是
36 strbuf = str;
上看,strbuf 都是字符串
那么 strbuf[i] = 'x' 这样写是无效的,虽然不报错
同样 ord(strbuf[i]) 也是不能返回正确值的对应 ord(strbuf[i]) 的 js 是
strbuf.charCodeAt(i)对应 chr(n) 的 js 是
String.fromCharCode(n)没有认真去看你提供的php同名函数,但至少你的 js 取值、赋值部分已经就出问题了另外:
DZ 的发行版是分 utf-8 和 gbk 的
由于字符内码的原因,utf-8 版中的 Authcode 编码结果是不能在 gbk 版中正确解码的(解出的还是utf-8的)
当然如果不含有中文是没有问题的,这一点你在测试的时候一定要注意那个 Base64 类也是针对 utf-8 编码的。如果 php 端不是 utf-8 的,你也不能得到相同的结果
function authcode(str, operation, key, expiry) {
var operation = operation ? operation : 'DECODE';
var key = key ? key : '';
var expiry = expiry ? expiry : 0;
var ckey_length = 4;
key = md5(key);
// 密匙a会参与加解密
var keya = md5(key.substr(0, 16));
// 密匙b会用来做数据完整性验证
var keyb = md5(key.substr(16, 16));
// 密匙c用于变化生成的密文
var keyc = ckey_length ? (operation == 'DECODE' ? str.substr(0, ckey_length): md5(microtime()).substr(-ckey_length)) : '';
// 参与运算的密匙
var cryptkey = keya+md5(keya+keyc);
var string="";
if(operation == 'DECODE') {
string =Base64.decode(str.substr(ckey_length));
}
else {
expiry = expiry ? expiry + time() : 0;
tmpstr = expiry.toString();
if(tmpstr.length>=10)
string = tmpstr.substr(0,10)+md5(str+keyb).substr(0, 16)+str;
else {
var count = 10 - tmpstr.length;
for(var i=0;i<count;i++) {
tmpstr = '0'+tmpstr;
}
string = tmpstr+md5(str+keyb).substr(0, 16)+str;
}
}
var box = new Array(256);
for(var i=0; i < 256; i++) {
box[i] = i;
}
var rndkey = new Array();
// 产生密匙簿
for(var i=0; i < 256; i++) {
rndkey[i] = cryptkey.charCodeAt(i % cryptkey.length);
}
// 用固定的算法,打乱密匙簿,增加随机性,好像很复杂,实际上对并不会增加密文的强度
for(var j = i = 0; i < 256; i++) {
j = (j + box[i] + rndkey[i]) % 256;
tmp = box[i];
box[i] = box[j];
box[j] = tmp;
}
// 核心加解密部分
var result = '';
for(var a = j = i = 0; i < string.length; i++) {
a = (a + 1) % 256;
j = (j + box[a]) % 256;
tmp = box[a];
box[a] = box[j];
box[j] = tmp;
result+=String.fromCharCode(string.charCodeAt(i) ^ (box[(box[a] + box[j]) % 256]));
}
if(operation == 'DECODE') {
var s="";
if((result.substr(0, 10) == 0 || result.substr( 0, 10) - time() > 0) && result.substr(10, 16) == md5(result.substr(26)+keyb).substr(0, 16)) {
s = result.substr(26);
}
}
else {
var s = Base64.encode(result);
var regex = new RegExp('=', "g");
s = s.replace(regex, '');
s = keyc+s;
} return s;
}
这里基本上没采用替代版的CHR,ORD,等,都用的JS只带的。我的测试页面编码都是UTF-8编码。这里的Base64.encode与php的base64_encode结果一样。前文说的ord,chr 都有提供JS版本的。chr:http://phpjs.org/functions/chr/ord:http://phpjs.org/functions/ord/