Java 混合字符串的SHA-1哈希

Java 混合字符串的SHA-1哈希,java,hash,byte,sha,Java,Hash,Byte,Sha,我必须解析如下“一些文本”这样的内容,我能把整个内容读入一个字符串而不破坏40字节的散列部分吗 问题是散列不会出现,所以我不想在阅读时处理它 编辑:我忘了提到40字节的散列是2x20字节的散列,没有编码原始字节。SHA-1散列的长度是20字节(160位)。如果处理的是40个字符的散列,那么它们可能是散列的ASCII表示,因此只包含字符0-9和a-f。如果是这种情况,那么您应该能够在Java中毫无困难地读取和操作字符串。SHA-1哈希值的长度为20字节(160位)。如果处理的是40个字符的散列,那

我必须解析如下“一些文本”这样的内容,我能把整个内容读入一个字符串而不破坏40字节的散列部分吗

问题是散列不会出现,所以我不想在阅读时处理它


编辑:我忘了提到40字节的散列是2x20字节的散列,没有编码原始字节。

SHA-1散列的长度是20字节(160位)。如果处理的是40个字符的散列,那么它们可能是散列的ASCII表示,因此只包含字符0-9和a-f。如果是这种情况,那么您应该能够在Java中毫无困难地读取和操作字符串。

SHA-1哈希值的长度为20字节(160位)。如果处理的是40个字符的散列,那么它们可能是散列的ASCII表示,因此只包含字符0-9和a-f。如果是这样的话,那么您应该能够毫不费力地在Java中读取和操作字符串。

更多的细节可能会有用,但我认为答案是您应该没事

/** Lookup table: character for a half-byte */
    static final char[] CHAR_FOR_BYTE = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    /** Encode byte data as a hex string... hex chars are UPPERCASE */
    public static String encode(byte[] data){
        if(data == null || data.length==0){
            return null;
        }
        char[] store = new char[data.length*2];
        for(int i=0; i<data.length; i++){
            final int val = (data[i]&0xFF);
            final int charLoc=i<<1;
            store[charLoc]=CHAR_FOR_BYTE[val>>>4];
            store[charLoc+1]=CHAR_FOR_BYTE[val&0x0F];
        }
        return new String(store);
    }
您没有说明SHA-1哈希是如何编码的(常见的可能性包括“无”(原始字节)、Base64和hex)。由于SHA-1生成一个20字节(160位)的散列,我猜它将使用十六进制编码,因为这将使所需的空间增加一倍,达到您提到的40字节。使用该编码,2个字符将用于编码散列中的每个字节,使用符号0到9和A到F。这些都是ASCII字符,因此您是安全的

Base64编码也可以工作(虽然可能不是您所要求的,因为它会将大小增加约1/3,使您的字节数远远小于40字节),因为Base64中使用的每个字符也是ASCII字符


如果直接使用原始字节,则会出现问题,因为某些值不是有效字符。

更多详细信息可能会有用,但我认为答案是您应该没事

您没有说明SHA-1哈希是如何编码的(常见的可能性包括“无”(原始字节)、Base64和hex)。由于SHA-1生成一个20字节(160位)的散列,我猜它将使用十六进制编码,因为这将使所需的空间增加一倍,达到您提到的40字节。使用该编码,2个字符将用于编码散列中的每个字节,使用符号0到9和A到F。这些都是ASCII字符,因此您是安全的

Base64编码也可以工作(虽然可能不是您所要求的,因为它会将大小增加约1/3,使您的字节数远远小于40字节),因为Base64中使用的每个字符也是ASCII字符


如果直接使用原始字节,则会出现问题,因为某些值不是有效字符。

好的,现在您已经澄清了这些是原始字节


不,您不能将其作为字符串读入Java,您需要将其作为原始字节读入。

好的,现在您已经澄清了这些是原始字节

/** Lookup table: character for a half-byte */
    static final char[] CHAR_FOR_BYTE = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    /** Encode byte data as a hex string... hex chars are UPPERCASE */
    public static String encode(byte[] data){
        if(data == null || data.length==0){
            return null;
        }
        char[] store = new char[data.length*2];
        for(int i=0; i<data.length; i++){
            final int val = (data[i]&0xFF);
            final int charLoc=i<<1;
            store[charLoc]=CHAR_FOR_BYTE[val>>>4];
            store[charLoc+1]=CHAR_FOR_BYTE[val&0x0F];
        }
        return new String(store);
    }

不,您不能将其作为字符串读入Java,您需要将其作为原始字节读入。

工作代码:
/** Lookup table: character for a half-byte */
    static final char[] CHAR_FOR_BYTE = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    /** Encode byte data as a hex string... hex chars are UPPERCASE */
    public static String encode(byte[] data){
        if(data == null || data.length==0){
            return null;
        }
        char[] store = new char[data.length*2];
        for(int i=0; i<data.length; i++){
            final int val = (data[i]&0xFF);
            final int charLoc=i<<1;
            store[charLoc]=CHAR_FOR_BYTE[val>>>4];
            store[charLoc+1]=CHAR_FOR_BYTE[val&0x0F];
        }
        return new String(store);
    }
将字节字符串输入转换为十六进制字符,这在几乎所有字符串编码中都应该是安全的。使用我在你的另一个问题中发布的代码将十六进制字符解码回原始字节

/** Lookup table: character for a half-byte */
    static final char[] CHAR_FOR_BYTE = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    /** Encode byte data as a hex string... hex chars are UPPERCASE */
    public static String encode(byte[] data){
        if(data == null || data.length==0){
            return null;
        }
        char[] store = new char[data.length*2];
        for(int i=0; i<data.length; i++){
            final int val = (data[i]&0xFF);
            final int charLoc=i<<1;
            store[charLoc]=CHAR_FOR_BYTE[val>>>4];
            store[charLoc+1]=CHAR_FOR_BYTE[val&0x0F];
        }
        return new String(store);
    }
/**查找表:半字节字符*/
静态final char[]char_FOR_BYTE={0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
/**将字节数据编码为十六进制字符串。。。十六进制字符是大写的*/
公共静态字符串编码(字节[]数据){
if(data==null | | data.length==0){
返回null;
}
char[]store=new char[data.length*2];
对于(int i=0;i4];
存储[charLoc+1]=CHAR_代表字节[val&0x0F];
}
返回新字符串(存储);
}

工作代码: 将字节字符串输入转换为十六进制字符,这在几乎所有字符串编码中都应该是安全的。使用我在你的另一个问题中发布的代码将十六进制字符解码回原始字节

/** Lookup table: character for a half-byte */
    static final char[] CHAR_FOR_BYTE = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    /** Encode byte data as a hex string... hex chars are UPPERCASE */
    public static String encode(byte[] data){
        if(data == null || data.length==0){
            return null;
        }
        char[] store = new char[data.length*2];
        for(int i=0; i<data.length; i++){
            final int val = (data[i]&0xFF);
            final int charLoc=i<<1;
            store[charLoc]=CHAR_FOR_BYTE[val>>>4];
            store[charLoc+1]=CHAR_FOR_BYTE[val&0x0F];
        }
        return new String(store);
    }
/**查找表:半字节字符*/
静态final char[]char_FOR_BYTE={0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
/**将字节数据编码为十六进制字符串…十六进制字符为大写*/
公共静态字符串编码(字节[]数据){
if(data==null | | data.length==0){
返回null;
}
char[]store=new char[data.length*2];
对于(int i=0;i4];
存储[charLoc+1]=CHAR_代表字节[val&0x0F];
}
返回新字符串(存储);
}

将其作为字节流从输入流中读取,然后从流中删除字符串,如下所示:

String s = new String(Arrays.copyOfRange(bytes, 0, bytes.length-40));
然后将字节设置为:

byte[] hash = Arrays.copyOfRange(bytes, s.length-1, bytes.length-1)

将其作为字节流从输入流中读取,然后从流中删除字符串,如下所示:

String s = new String(Arrays.copyOfRange(bytes, 0, bytes.length-40));
然后将字节设置为:

byte[] hash = Arrays.copyOfRange(bytes, s.length-1, bytes.length-1)

编辑以提及40字节散列为2,20字节sha-1散列无编码。编辑以提及40字节散列为2,20字节sha-1散列无编码。你最终得到了什么?你最终得到了什么?