yuesir
老生
老生
  • UID77
  • 粉丝0
  • 关注0
  • 发帖数2
阅读:509回复:1

JAVA 和 PHP md5 结果不一致

楼主#
更多 发布于:2018-03-07 19:41

问题:已有数据库的分表规则是由 JAVA 程序(如下)实现的一致性哈希算法来完成的,现在 PHP 程序要去读库,需要

自己通过 PHP 实现 JAVA 的一致性哈希算法,但是发现 JAVA 代码中的 md5 方法 PHP 不知道如何实现。查了资料

说是可以通过 $raw_md5=unpack("c*", md5($orign,true)); 来实现类似 JAVA md5 函数返回的字节数组,但实际

实现得到的结果和运行 JAVA 程序不一致

public class TableHashRouteUtils {

    private TableHashRouteUtils() {
    }


/**
*  分表时选中类型:50张分
*/
public static final String TABLE_SELECT_FIFTY = "fifty";

/**
*  分表时选中类型:100张分
*/
public static final String TABLE_SELECT_ONE_HANDRED = "oneHundred";

    /**
     * 待添加入Hash环的表(50张)
     */
    private static String[] fiftyTables = {"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",
            "31", "32", "33", "34", "35", "36", "37", "38", "39", "40",
            "41", "42", "43", "44", "45", "46", "47", "48", "49", "50"};
 
    //Hash环列表(50张)
    private static List<String> fiftyServers = Arrays.asList(fiftyTables);
    //Hash环的表(100张)
    private static List<String> oneHundredServers = Arrays.asList(oneHundredTables);
    //根据字段获取hash值选择器(50张)
    private static ConsistentHashSelector fiftySelector = new ConsistentHashSelector(fiftyServers);
 
    /**
     *传入分片字段获取表分片位置
     *
     * @param userId
     * @return
     */
    public static String doSelect(Object shardingValue,String type) {
     if(TABLE_SELECT_FIFTY.equals(type)){
     return fiftySelector.select(String.valueOf(shardingValue));
     }else{
     return oneHundredSelector.select(String.valueOf(shardingValue));
     }
    }

    private static final class ConsistentHashSelector {
        private final TreeMap<Long, String> virtualServers;
        private final int replicaNumber;

        /**
         * 找到key所在的分片位置
         *
         * @param key
         * @return
         */
        public String select(String key) {
            byte[] digest = md5(key);
            return selectForKey(hash(digest, 0));
        }

        /**
         * 通过hash值获取在hash环中的位置
         *
         * @param hash
         * @return
         */
        private String selectForKey(long hash) {
            Long key = hash;
            if (!virtualServers.containsKey(key)) {
                SortedMap<Long, String> tailMap = virtualServers.tailMap(key);
                if (tailMap.isEmpty()) {
                    key = virtualServers.firstKey();
                } else {
                    key = tailMap.firstKey();
                }
            }
            return virtualServers.get(key);
        }

        /**
         * 获取hash值
         *
         * @param digest
         * @param number
         * @return
         */
        private long hash(byte[] digest, int number) {
            return (((long) (digest[3 + number * 4] & 0xFF) << 24)
                    | ((long) (digest[2 + number * 4] & 0xFF) << 16)
                    | ((long) (digest[1 + number * 4] & 0xFF) << 8)
                    | (digest[number * 4] & 0xFF))
                    & 0xFFFFFFFFL;
        } /**
         * md5加密
         *
         * @param value
         * @return
         */
        private byte[] md5(String value) {
            MessageDigest md5;
            try {
                md5 = MessageDigest.getInstance("MD5");
            } catch (NoSuchAlgorithmException e) {
                throw new IllegalStateException(e.getMessage(), e);
            }
            md5.reset();
            byte[] bytes = null;
            try {
                bytes = value.getBytes("UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new IllegalStateException(e.getMessage(), e);
            }
            md5.update(bytes);
            return md5.digest();
        }
    }
public static void main(String[] args) {
System.out.println(doSelect("6340194558965481472L",TABLE_SELECT_FIFTY));
}
}




我自己写的 PHP 测试代码如下,得到的结果和 JAVA md5 函数得到的结果不一致

$res = unpack("c*", md5('10',true));
var_dump($res);
yuesir
老生
老生
  • UID77
  • 粉丝0
  • 关注0
  • 发帖数2
沙发#
发布于:2018-03-11 08:19
已经解决了~
游客

返回顶部