mysql取字符串hash值的问题

SQL code


DELIMITER $$

CREATE
    /*[DEFINER = { user | CURRENT_USER }]*/
    PROCEDURE `test`.`HashValue`(IN accountName CHAR(32))
    /*LANGUAGE SQL
    | [NOT] DETERMINISTIC
    | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
    | SQL SECURITY { DEFINER | INVOKER }
    | COMMENT 'string'*/
    BEGIN
    SET @size = LENGTH(accountName);
    SET @pos = 1;
    SET @hashValue = 0;
    WHILE @pos<@size+1 DO
        SET @nCh = SUBSTRING(accountName,@pos,1);
        SET @hashValue = @hashValue + ASCII(@nCh);
        SET @pos = @pos + 1;
    END WHILE;
    
    SELECT @size,@hashValue;

    END$$

DELIMITER ;


我想计算一个字符串的hash值,算法如上,以上如果是纯英文的是没有问题的,比如 select call("abc");
但是如果是中文的话就有问题了,比如select call("我");,由于是UTF8的编码,所以select length("我");是三个字节,但是substring();这个函数的第二个参数pos的含义不是按照字节数来递增的,也就是说,asscii(substring("我",1,1))是230,而asscii(substring("我",2,1))就是0了。
所以select call("我")的结果就是3,230,其实就是取了“我”的一个字节的ascii值

求解了,有么有替代substring()的函数之类或者其他的办法

作者: qqwx_1986   发布时间: 2011-06-07

调用应该是 CALL HashValue("我");
上面写错了,不好意思

作者: qqwx_1986   发布时间: 2011-06-07

没有取字节的函数,如果需要则建议先转成HEX,然后再取其中的数字。

作者: ACMAIN_CHM   发布时间: 2011-06-07

引用 2 楼 acmain_chm 的回复:

没有取字节的函数,如果需要则建议先转成HEX,然后再取其中的数字。

这方法不错,3Q

附上成功代码:

SQL code

DELIMITER $$

CREATE
    PROCEDURE `test`.`HashValue`(IN str CHAR(32))
    BEGIN
    
    SET @pos = 1;
    SET @hashValue = 0;
    SET @szHex = HEX(str);
    SET @size = LENGTH(@szHex);
    WHILE @pos<@size+1 DO
        SET @cCh = SUBSTRING(@szHex,@pos,2);
        SET @nCh =CAST(ASCII(UNHEX(@cCh)) AS UNSIGNED);
        SET @hashValue = @hashValue + @nCh;
        SET @pos = @pos + 2;
    END WHILE;

    SELECT @hashValue;
    END$$

DELIMITER ;

作者: qqwx_1986   发布时间: 2011-06-07