事情是这样。前段时间跟同学在校内架起了一个PT网站,代码是从sourceforge.org上下的tbdev。
因为对mysql不熟,数据库默认字符集设为了utf-8
前台页面的charset设成了GBK
正常运行了一段时间。但现在网站要进行升级。字符集问题出现了。
phpmyadmin查看文本字段里面的信息是乱码,不能正常查询。
于是查资料,把gbk编码成功转成了UTF-8编码。前台页面也设成了UTF-8。虽然中文显示正常了,但最关键的用户注册信息有问题。
我要保留原网站的用户注册信息,关键是密码。站点采用MD5方式加密。数据库中有个secret字段 是 varchar类型。 字符集为 UTF-8
保存的是以GBK方式编码的 0-255的随机ASCII字符还有个passhash字段 是 varchar类型。字符集为UTF-8
保存的是进行如下计算的字符串
md5($row["secret"] . $password . $row["secret"])登陆时作如下判断
if ($row["passhash"] != md5($row["secret"] . $password . $row["secret"]))
bark();升级时为解决乱码问题。在连接数据库之前执行了
mysql_query("SET NAMES utf8");但是如果Connection指定字符集为UTF-8后,MD5计算出的passhash就变了。
如果执行mysql_query("SET NAMES latin1");
则MD5计算出的结果正常。我试过将secret字段中的文本转换编码,但没有成功。MD5计算出的passhash还是不一样。我想到一个方法就是把secret字段转化成 blob类型。我测试过,二进制类型的数据传输时不受连接字符集编码的影响。
但是我现在不知道该如何把字符串转化为二进制流存入 blob类型的字段中。或者大虾位有没有别的解决方法?即保证字符集统一,又能保证用户正确登陆?
因为对mysql不熟,数据库默认字符集设为了utf-8
前台页面的charset设成了GBK
正常运行了一段时间。但现在网站要进行升级。字符集问题出现了。
phpmyadmin查看文本字段里面的信息是乱码,不能正常查询。
于是查资料,把gbk编码成功转成了UTF-8编码。前台页面也设成了UTF-8。虽然中文显示正常了,但最关键的用户注册信息有问题。
我要保留原网站的用户注册信息,关键是密码。站点采用MD5方式加密。数据库中有个secret字段 是 varchar类型。 字符集为 UTF-8
保存的是以GBK方式编码的 0-255的随机ASCII字符还有个passhash字段 是 varchar类型。字符集为UTF-8
保存的是进行如下计算的字符串
md5($row["secret"] . $password . $row["secret"])登陆时作如下判断
if ($row["passhash"] != md5($row["secret"] . $password . $row["secret"]))
bark();升级时为解决乱码问题。在连接数据库之前执行了
mysql_query("SET NAMES utf8");但是如果Connection指定字符集为UTF-8后,MD5计算出的passhash就变了。
如果执行mysql_query("SET NAMES latin1");
则MD5计算出的结果正常。我试过将secret字段中的文本转换编码,但没有成功。MD5计算出的passhash还是不一样。我想到一个方法就是把secret字段转化成 blob类型。我测试过,二进制类型的数据传输时不受连接字符集编码的影响。
但是我现在不知道该如何把字符串转化为二进制流存入 blob类型的字段中。或者大虾位有没有别的解决方法?即保证字符集统一,又能保证用户正确登陆?
我在数据库中建了一个结构相同的users_bak表
仅仅是把secret字段改成了blob类型。转化代码如下:<?
require_once("include/bittorrent.php");dbconn(); //数据库连接函数;mysql_query("SET NAMES latin1");$res = mysql_query("SELECT id, passhash, secret, enabled FROM users WHERE username = 'testusername'");
$row = mysql_fetch_assoc($res);$secr=$row["secret"];
$password="test";print "secret:".$row["secret"]."/passhash:".$row["passhash"];
print "<br>md5:".md5($row["secret"] . $password . $row["secret"]);mysql_query("SET NAMES utf8");
mysql_query("UPDATE users_bak SET secret='".$row["secret"]."' WHERE username='testusername'");print "<br>Convert finish.";
?>
结果读出的值经md5计算,还是不一样。
再导入到 字符集为 GBK 的 tbdev_gbk 数据库中mysql -u root -p --default-character-set=gbk tbdev_gbk < user.sql其它字段由乱码转化成了正常的中文。
但secret字段中的值变了。
读出来的字符串经MD5加密后,结果也变了。
不能正常登陆
可是现在要保留原网站的注册信息。我必须得想办法转化下原来的secret字段。原来的网站数据库字符集是UTF-8 Connection是latin1 前台页面是GBK
这就是问题的根源…… 痛苦……
万分感谢!~!你的话提醒了我~!问题解决!
方法如下:就像把GBK转成UTF-8的方法一样。
把users表导入。单独改 secret字段的编码为 blob
再把数据导入。这样 secret字段的值就由字符串转化成了二进制数据。读取时不受 Connection字符集的影响~使用latin1和UTF-8都得出了正确结果。
用户名为汉字的帐号也能正确登陆了~!哈哈~~谢谢各位!!!!马上给分!
这是中间步骤。
之后再以同样的方法把gbk数据转化成UTF-8数据导入最终的UTF-8数据库中。呵呵。问题解决了,谢谢帮助!
原始数据库为UTF-8 Connection为Latin1 前台页面为GBK
数据是以GBK编码保存在UTF-8的数据库中的。
phpmyadmin显示表中内容为乱码。导出数据
mysqldump -u root -p --default-character-set=latin1 --set-charset=false tbdev > tbdev_latin1_gbk.sql
用UltraEdit 将 utf8_general_ci 替换为 gbk_chinese_ci、utf8替换为gbk 保存
创建GBK数据库: create database tbdev_gbk character set 'gbk' COLLATE 'gbk_chinese_ci';
导入数据到GBK数据库
mysql -u root -p --default-character-set=gbk tbdev_gbk < tbdev_latin1_gbk.sql
此时phpmyadmin正确显示汉字。再将GBK编码转化为UTF-8编码mysqldump -u root -p --default-character-set=utf8 --set-charset=false tbdev > tbdev_gbk_utf8.sql
用UltraEdit 将 gbk 替换为 utf8 保存
创建UTF-8数据库: create database tbdev_utf8 character set 'utf8' COLLATE 'utf8_general_ci';
导入数据到UTF-8数据库
mysql -u root -p --default-character-set=utf-8 tbdev_utf8 < tbdev_gbk_utf8.sql
此时phpmyadmin正确显示汉字。成功将GBK编码转为UTF-8编码。
但由于secret字段影响,中文帐号无法正常登陆。单独导出users表
mysqldump -u root -p --default-character-set=utf8 --set-charset=false tbdev_utf8 users > users.sql
用UltraEdit 将 secret 字段的类型改为 blob 保存
导入users表到数据库
mysql -u root -p --default-character-set=utf-8 tbdev_utf8 < users.sql转化完毕。
经测试,中英文帐户均能正常登陆。且不受 Connection字符集设置影响。
站点乱码问题解决!在此再次对楼上大虾们的帮助表示感谢!!谢谢!!!!!