...pudding - diary

この日記は https://yapud.hatenablog.com/ に引っ越し中


2014-11-19

_ [Software] MySQL 5.1 で md5() に対して upper() が効かない

MySQL 環境で md5() の結果は小文字で表示されますが、これを大文字で処理したくて、単純に upper() 通せば良いだろうとやってみました。手元にあった MySQL 5.6.21 で試してみたところの実行結果はこんなかんじ

mysql> select md5('test');
+----------------------------------+
| md5('test')                      |
+----------------------------------+
| 098f6bcd4621d373cade4e832627b4f6 |
+----------------------------------+
1 row in set (0.00 sec)
 
mysql> select upper(md5('test'));
+----------------------------------+
| upper(md5('test'))               |
+----------------------------------+
| 098F6BCD4621D373CADE4E832627B4F6 |
+----------------------------------+
1 row in set (0.00 sec)

upper() で大文字になりました。普通ですね。なんの問題もありません。

さてこのコードを実際に実行するのは別のサーバです。そっちで試してみます。MySQL 5.1.73 です。

mysql> select md5('test');
+----------------------------------+
| md5('test')                      |
+----------------------------------+
| 098f6bcd4621d373cade4e832627b4f6 |
+----------------------------------+
1 row in set (0.00 sec)
 
mysql> select upper(md5('test'));
+----------------------------------+
| upper(md5('test'))               |
+----------------------------------+
| 098f6bcd4621d373cade4e832627b4f6 |
+----------------------------------+
1 row in set (0.00 sec)

upper() 通したのに大文字にならない!なんで!おとなしく大文字になってよ文字列!

あれ?これ大文字にならなってことは普通の文字列じゃないんじゃないの?

mysql> select charset(md5('test'));
+----------------------+
| charset(md5('test')) |
+----------------------+
| binary               |
+----------------------+
1 row in set (0.00 sec)

ほう。確かに文字列じゃない。MySQL 5.6 の方は?

mysql> select charset(md5('test'));
+----------------------+
| charset(md5('test')) |
+----------------------+
| utf8                 |
+----------------------+
1 row in set (0.00 sec)

うわあこっちは文字列! 仕様が変わっとるんか!

マニュアルを引いてみよう。MySQL :: MySQL 5.5 Reference Manual :: 12.13 Encryption and Compression Functions の MD5(str) の項を見てみると。

As of MySQL 5.5.3, the return value is a nonbinary string in the connection character set. Before 5.5.3, the return value is a binary string; see the notes at the beginning of this section about using the value as a nonbinary string.

MySQL 5.5.3 以降だと普通の文字列で出るけど、それ以前のバージョンだとバイナリ文字列で出るよと。そういうのは先に言うてよー!めっちゃびっくりしたし! ほかにも SHA1() とか SHA2() とかも似たような境遇です。

じゃあ、とりあえず普通の文字列に変換したら通るかな。

mysql> select charset(convert(md5('test') using utf8));
+------------------------------------------+
| charset(convert(md5('test') using utf8)) |
+------------------------------------------+
| utf8                                     |
+------------------------------------------+
1 row in set (0.00 sec)
 
mysql> select upper(convert(md5('test') using utf8));
+----------------------------------------+
| upper(convert(md5('test') using utf8)) |
+----------------------------------------+
| 098F6BCD4621D373CADE4E832627B4F6       |
+----------------------------------------+
1 row in set (0.00 sec)

md5() の結果を utf8 に変換してから upper() に食わせたところ問題なく処理出来ました。よかった。


2014年
11月
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30
Twitter : @moriya_jp