2011-05-04 57 views
21

Tôi đang cố gắng chuyển đổi một chuỗi thập lục phân thành số nguyên. Chuỗi thập lục phân được tính từ hàm băm (sha-1). Tôi nhận được lỗi này: java.lang.NumberFormatException. Tôi đoán nó không giống như biểu diễn chuỗi của hệ thập lục phân. Làm thế nào tôi có thể đạt được điều đó. Đây là mã của tôi:Hệ thập lục phân đến số nguyên trong Java

public Integer calculateHash(String uuid) { 

    try { 
     MessageDigest digest = MessageDigest.getInstance("SHA1"); 
     digest.update(uuid.getBytes()); 
     byte[] output = digest.digest(); 

     String hex = hexToString(output); 
     Integer i = Integer.parseInt(hex,16); 
     return i;   

    } catch (NoSuchAlgorithmException e) { 
     System.out.println("SHA1 not implemented in this system"); 
    } 

    return null; 
} 

private String hexToString(byte[] output) { 
    char hexDigit[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 
      'A', 'B', 'C', 'D', 'E', 'F' }; 
    StringBuffer buf = new StringBuffer(); 
    for (int j = 0; j < output.length; j++) { 
     buf.append(hexDigit[(output[j] >> 4) & 0x0f]); 
     buf.append(hexDigit[output[j] & 0x0f]); 
    } 
    return buf.toString(); 

} 

Ví dụ, khi tôi vượt qua chuỗi này: _DTOWsHJbEeC6VuzWPawcLA, băm ông của mình: 0xC934E5D372B2AB6D0A50B9F0341A00ED029BDC15

Nhưng tôi nhận được: java.lang.NumberFormatException: Đối với chuỗi đầu vào: "0xC934E5D372B2AB6D0A50B9F0341A00ED029BDC15"

Tôi thực sự cần thực hiện việc này. Tôi có một bộ sưu tập các yếu tố được xác định bởi UUID của họ là chuỗi. Tôi sẽ phải lưu trữ các yếu tố đó nhưng hạn chế của tôi là sử dụng một số nguyên làm id của chúng. Đó là lý do tại sao tôi tính toán giá trị băm của tham số được đưa ra và sau đó tôi chuyển đổi thành một int. Có lẽ tôi đang làm điều này sai nhưng ai đó có thể cho tôi một lời khuyên để đạt được điều đó một cách chính xác !!

Cảm ơn sự giúp đỡ của bạn !!

+1

đầu tiên của tất cả các số là quá lớn đối với số nguyên thường xuyên. – Andrey

+1

Như Andrey nói, nó sẽ không vừa với một số nguyên thông thường. Nếu bạn vui mừng thay đổi sang java.math.BigInteger, bạn chỉ có thể 'trả về BigInteger mới (1, digest.digest())'. – eggyal

Trả lời

70

Tại sao bạn không sử dụng chức năng java cho rằng:

Nếu con số của bạn là nhỏ (nhỏ hơn của bạn), bạn có thể sử dụng: Integer.parseInt(hex, 16) để chuyển đổi một Hex - String vào một số nguyên.

String hex = "ff" 
    int value = Integer.parseInt(hex, 16); 

Đối với số lượng lớn như của bạn, sử dụng public BigInteger(String val, int radix)

BigInteger value = new BigInteger(hex, 16); 

@See javadoc:

+1

Tôi thực sự không nhận được câu trả lời này, không phải là những gì anh ta đã cố gắng trong 'Integer i = Integer.parseInt (hex, 16);'? – OscarRyz

+0

Ngoài việc loại bỏ phần '0x' ... Tôi không biết rằng điều này được cho phép .. và nếu bạn có thể đảm bảo rằng nó sẽ luôn là' 0xABC982..', thì bạn luôn có thể xóa 2 ký tự đầu tiên –

+1

Tôi nghĩ rằng bạn có nghĩa là để nhanh chóng một BigInteger mới trong dòng thứ ba của mã? Nó cũng phải hiệu quả hơn để xây dựng trực tiếp từ mảng byte hơn là biểu diễn chuỗi thập lục phân. – eggyal

0

SHA-1 tạo thông báo 160 bit (20 byte), quá lớn để được lưu trữ trong giá trị int hoặc long. Như Ralph gợi ý, bạn có thể sử dụng BigInteger.

Để nhận hàm băm int (không an toàn), bạn có thể trả về mã băm của mảng byte được trả về.

Ngoài ra, nếu bạn không thực sự cần SHA, bạn chỉ có thể sử dụng mã băm String của UUID.

+0

Tôi đã cố gắng sử dụng mã băm String của UUID nhưng tôi cũng nhận được IllegalArgumentException. Đây là lý do tại sao tôi thả UUID; Nhân tiện, tôi thậm chí không biết cách họ tạo ra UUID của họ, nó không phải là dự án của tôi – Dimitri

+0

Bởi "Mã băm chuỗi UUID" Tôi ngụ ý 'uuid.hashCode()' (sử dụng hàm 'String.hashCode()'). Tôi không thể thấy rằng đưa ra một IAE? –

+0

Vâng, tôi biết. Tôi vừa thử phương pháp này. Nhưng vấn đề là khi tôi thử String id = UUID.fromString (uuid) tôi nhận được một IllegalArgumentException. – Dimitri

-2

Đó là bởi vì byte[] output là tốt, và mảng byte, bạn có thể nghĩ về nó như một mảng byte đại diện cho mỗi một số nguyên, nhưng khi bạn thêm tất cả vào một chuỗi, bạn sẽ nhận được , đó là lý do. Bạn có thể có nó như là một mảng các số nguyên hoặc cố gắng tạo một thể hiện của BigInteger.

+0

Có thể chuyển đổi từ BigInteger sang Integer không? – Dimitri

+0

Chỉ khi giá trị của BigInteger không lớn hơn Integer.MAX_VALUE trong trường hợp này nó sẽ là. Xem: http://download.oracle.com/javase/6/docs/api/java/math/BigInteger.html#intValue() – OscarRyz

+2

Câu trả lời này về cơ bản là vô nghĩa. Một mảng các byte chỉ đơn giản là một số chính xác nhiều. Không trả lời câu hỏi. – EJP

0

Cuối cùng tôi tìm thấy câu trả lời cho câu hỏi của mình dựa trên tất cả các nhận xét của bạn. Cảm ơn, tôi đã thử cách này:

public Integer calculateHash(String uuid) { 

    try { 
     //.... 
     String hex = hexToString(output); 
     //Integer i = Integer.valueOf(hex, 16).intValue(); 
     //Instead of using Integer, I used BigInteger and I returned the int value. 
     BigInteger bi = new BigInteger(hex, 16); 
     return bi.intValue();` 
    } catch (NoSuchAlgorithmException e) { 
     System.out.println("SHA1 not implemented in this system"); 
    } 
    //.... 
} 

Giải pháp này không tối ưu nhưng tôi có thể tiếp tục với dự án của mình.Cảm ơn một lần nữa giúp đỡ của bạn

+0

Đừng trả lời câu hỏi của riêng bạn. Chỉnh sửa câu hỏi của bạn hoặc thêm nhận xét. – EJP

1

bạn có thể sử dụng phương pháp này: https://stackoverflow.com/a/31804061/3343174 nó chuyển đổi một cách hoàn hảo bất kỳ số thập lục phân (được trình bày như là một chuỗi) đối với một số thập phân

Các vấn đề liên quan