2012-08-07 2 views
2

MEID (길이 14의 16 진수)를 의사 ESN (길이 8의 16 진수)으로 변환 할 수있는 프로그램을 만들려고합니다. MEID에서 pESN을 얻는 방법은 이론상 상당히 간단합니다. 예를 들어 MEID가 0xA0000000002329 인 경우 pESN을 만들려면 SHA-1을 MEID에 적용해야합니다. A0000000002329의 SHA-1은 e3be267a2cd5c861f3c7ea4224df829a3551f1ab를 제공합니다. 이 결과의 마지막 6 자리 숫자를 취하여 0x80에 추가합니다. 결과는 0x8051F1AB입니다.SHA-1을 바이트 단위로 큰 16 진수에 어떻게 적용합니까?

public void sha1() throws NoSuchAlgorithmException { 

    String hexMEID = "A0000000002329"; 

    MessageDigest mDigest = MessageDigest.getInstance("SHA1");  
    byte[] b = new BigInteger(hexMEID,16).toByteArray();  

    byte[] result = mDigest.digest(b); 
    StringBuilder sb = new StringBuilder(); 

    for (int i = 0; i < result.length; i++) { 
     sb.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1)); 
    } 

    System.out.println(sb.toString()); 
} 

문제는이 방법을 사용하면, A0000000002329에 SHA-1 e3be267a2cd5c861f3c7ea4224df829a3551f1ab 대신 6ad447f040941bf43c0693d2b391c6c79fa58320 준다이다 :

지금 여기에 내가 지금까지 가지고있는 코드입니다. 나는 여기서 무엇을 잘못하고 있니?

누군가가 나에게 트릭은 MEID MEID를 대표하지 문자열을 나타내는 숫자로 SHA-1을 적용하는 것입니다

하는 힌트를 주었다. 바이트 단위로 처리해야하므로 한 번에 두 개의 16 진수 (두 개의 16 진수가 바이트를 만들기 때문에)를 입력해야하며 숫자가 이고 ASCII 문자가 아닌으로 해석되어야합니다 .

이 지침이 사실이라면 SHA-1을 바이트 단위로 내 16 진수에 적용하는 방법은 무엇입니까 ??

+0

"두 개의 16 진수가 한 바이트를 만듭니다"? 물론 @aviad도 – aviad

+0

입니다. 0xff == 255 (또는 16x16-1, 또는 2^8-1, 또는 8 비트)는 –

+0

@ Yanick Rochon입니다. "2 바이트 16 진수를 나타내는 데 1 바이트 필요합니다." – aviad

답변

2

Strelok가 반환 된 배열에 추가 바이트를 추가 BigInteger에 대한 문제를 발견했다 : 그래서 여기

는 ESN 코드 16 진수 MEID이 다음과 같이 표시됩니다. 이 간단한 버전도 예상 된 결과를 제공합니다.

String hexMEID = "A0000000002329"; 

MessageDigest mDigest = MessageDigest.getInstance("SHA1"); 

byte[] b = new BigInteger(hexMEID,16).toByteArray(); 

// skip the first byte set by BigInteger and retain only 7 bytes (length of MEID) 
byte[] result = mDigest.digest(Arrays.copyOfRange(b, 1, 8)); 

StringBuilder sb = new StringBuilder("80"); 

// need only the last 3 bytes 
for (int i=17; i<20; i++) { 
    sb.append(Integer.toHexString((result[i] & 0xff) | 0x100).substring(1)); 
} 

String pESN = sb.toString(); 
System.out.println(pESN); 
// -> 8051f1ab 
4

BigInteger을 사용하여 바이트 배열을 얻은 결과 작은 문제가 발생했습니다. MEID는 길이가 7 바이트 뿐이므로, BigInteger를 통해 펌핑하면 BigInteger가 부호를 보유하는 초 단위 바이트를 출력하므로 길이가 8 인 바이트 배열을 가져옵니다. 이 여분의 바이트는 입력의 SHA-1 해시가 완전히 다른 결과를 초래합니다. 너는 그것을 벗어야한다.

String hexMEID = "A0000000002329"; 
MessageDigest mDigest = MessageDigest.getInstance("SHA1"); 

byte[] input = new byte[ 7 ]; // MEIDs are only 7 bytes 

// Now copy the bytes from BigInteger skipping the extra byte added by it 
System.arraycopy(new BigInteger(hexMEID, 16).toByteArray(), 1, input, 0, 7); 

// Get the SHA-1 bytes 
byte[] result = mDigest.digest(input); 

// Build the SHA-1 String 
StringBuilder sb = new StringBuilder(); 
for (int i = 0; i < result.length; i++) 
{ 
    String hex = Integer.toHexString(0xFF & result[ i ]); 
    if (hex.length() == 1) 
    { 
     sb.append('0'); 
    } 
    sb.append(hex); 
} 

String sha1 = sb.toString(); 
// Grab the last 6 characters of the SHA-1 hash 
String lastSix = sha1.substring(sha1.length() - 6); 
// And prepend '80', now you have the ESN 
System.out.println("80" + lastSix); 
// Will print 8051f1ab which is exactly what you want 
관련 문제