将PHP中的SHA1哈希转换为JAVA代码

时间:2014-06-17 09:03:44

标签: java php sha1

嘿伙计我有问题,我必须将PHP转换为Java ...

Php函数以原始格式创建sha1哈希并对其进行编码。

strtolower(urlencode(sha1("asfasfasdf", true)));

OUT:%bep%c3%9cc%dc%e4%89%f6n%0cw%fb%a3%95%ba%d8%c9r%82

在java中我尝试过:

public static String buildIdentity(String identity) {
        try {
            return URLEncoder.encode(toSHA1(identity.getBytes())).toLowerCase();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String toSHA1(byte[] convertme) throws UnsupportedEncodingException{
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("SHA-1");
            md.update(convertme);
            byte[] res = md.digest();
            return new String(res);
        }
        catch(NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }


System.out.println(Utils.buildIdentity("asfasfasdf"));

但输出结果为:%ef%bf%bdp%c3%9cc%ef%bf%bd%ef%bf%bd%ef%bf%bdn%0cw%ef%bf%bd%ef%bf%bd%ef%bf%bdr%ef%bf%bd

请帮助我:(

找到解决方案!

public static String buildIdentity(String identity) {
    try {
        return URLEncoder.encode( new String(toSHA1(identity.getBytes("ISO-8859-1")), "ISO-8859-1"), "ISO-8859-1").toLowerCase();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return null;
}

public static byte[] toSHA1(byte[] convertme){
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        md.update(convertme);
        return md.digest();
    }
    catch(NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return null;
}

2 个答案:

答案 0 :(得分:0)

new String(byte[])使用平台默认编码将字节转换为字符。对我来说,如果你从new String(res, "iso-8859-1");方法返回toSHA1,它就可以了。这应该是好的,因为“前256个代码点与ISO-8859-1的内容相同,以便使转换现有的西方文本变得微不足道。” (来自Wikipedia)。

但这涉及到字符串的不必要转换。相反,如果您不想添加依赖项,我将使用apache commons中的URLCodec类或复制粘贴this

默认编码问题也适用于identity.getBytes()调用:您应在此处指定编码。它现在可能有效,但如果部署到生产服务器,它可能无法正常工作。

使用URLCodec固定代码:

public static String buildIdentity(String identity) {
    try {
        return new String(new URLCodec().encode(toSHA1(identity.getBytes("utf-8"))), "iso-8859-1");
    } catch (UnsupportedEncodingException e) {
        // should never happen, utf-8 and iso-8859-1 support is required by jvm specification. In any case, we rethrow.
        throw new RuntimeException(e);
    }
}

public static byte[] toSHA1(byte[] convertme) throws UnsupportedEncodingException {
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        md.update(convertme);
        return md.digest();
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    }
}

public static void main(String[] args) {
    System.out.println(buildIdentity("asfasfasdf"));
}

答案 1 :(得分:0)

您的代码忽略了Java字符编码问题。在buildIdentity方法中,您在没有参数的字符串上调用getBytes,因此将使用您平台的默认字符编码。这可能会导致问题,具体取决于您的平台;要在指定编码的平台之间获得可重现的结果,例如identity.getBytes("UTF-8")

toSHA1方法中,您无需指定编码即可调用构造函数new String(res)。这里的事情很可能出错。如果您的操作系统的字符编码与ISO-8859-1不同,则某些字节将替换为具有与原始字节不同的数值的字符,然后当您使用{{1}对其进行编码时},你不会得到你期望的结果。因此,请使用URLEncoder.encode

似乎Java生成的哈希比PHP生成的哈希更长。但是,如果编码是正确的,那么它们应该以相同的字符串开始,并且您应该能够调用new String(res, "ISO-8859-1")获取要编码的正确数量的字符。