Quantos caracteres diferentes em SHA-512 [RESOLVIDO]

7 respostas
A

Pessoal, andei pesquisando mas não encontrei nada. Parte do meu projeto analisa algumas hashs SHA-512 e verifica quantos caracteres diferentes tem dentro dela.

Criado o código, testei e me deparei com um resultado. Todas as hashs analisadas possuem 16 caracteres diferentes, nunca menos, nunca mais.
Alguém sabe me informar se esse número é imutável ou eu dei muita sorte e existem SHA-512 com outras quantidades de caracteres diferentes?

Obrigado galera :thumbup:

7 Respostas

A

Só uma pergunta: isso não teria relação com a base hexadecimal não?

[]'s

M

SHA e suas variantes (assim como o MD5) são algoritmos criptográficos de hash, que resultam sempre em um número fixo de bits. No caso do SHA-512 ele retorna um hash de 512 bits (o nome não é mera coincidência) para qualquer frase/arquivo/conjunto de bits que passar pelo algoritmo. Portanto não é possível determinar o “número de caracteres” a partir de um hash.

Algumas referências:
http://en.wikipedia.org/wiki/SHA_hash_functions
http://pt.wikipedia.org/wiki/SHA1#SHA-512_hashes
http://pt.wikipedia.org/wiki/MD5

C

AUser:
Só uma pergunta: isso não teria relação com a base hexadecimal não?

[]'s

Acho que o que ele quer saber é se não é possível sair um hash assim:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

E eu acho que é possível sim, basta vc ter uma amostra populacional suficientemente grande.
Digo acho pois nunca estudei a fundo o SHA(nem MD5, ou qualquer outro algoritmo de hash), mas que eu me lembre não existe nada que impeça isso

T

Para todos os efeitos, você pode considerar um SHA-512 como um número aleatório.

Existem apenas 16 valores de SHA-512 (um número hexadecimal de 128 dígitos) em um universo de 2^512 valores possíveis. Ou seja, a probabilidade de você ter um dado qualquer cujo SHA-512 seja de 128 dígitos repetidos é de:
16 * 2 elevado a 512 = 1,19 vezes 10 elevado a menos 153.

Um número realmente absurdo, considerando que o número de partículas no universo é de 10 elevado a 87 ( http://www.strangehorizons.com/2001/20010402/biggest_numbers.shtml ).

A única forma de conseguir achar um dado que tenha esse hash é você conseguir, de alguma forma, “quebrar” esse hash (isso requer, obviamente, você ser um excelente criptógrafo - apenas recentemente é que um chinês afirmou que conseguiu “quebrar” o MD5), de forma que você consiga construir um dado que tenha um determinado hash.

T

Além disso, você quer saber se pode haver um caso em que apareçam apenas 15 dígitos hexadecimais diferentes em um SHA-512, em vez dos 16 diferentes que você encontrou? Pode sim, vamos calcular a probabilidade, que é de 0,17%.

A probabilidade de aparecer um determinado dígito é de 1/16. Então a probabilidade de não aparecer é de 1 - 1/16 = 15/16.
Há 128 dígitos hexadecimais em um SHA-512.
Digamos que queremos um SHA-512 que não tenha um determinado dígito (digamos o dígito 0).
A probabilidade de termos um SHA-512 que não tem o dígito 0 é de (15/16) elevado a 128, ou seja, 1,0684808453952617024956635126888e-4 = 0,010684808453952617024956635126888%.
Como há 16 dígitos possíveis, então devemos multiplicar essa probabilidade por 16. Isso dá:
0,1709569352632418723993061620302 %.

Ou seja, você teria de calcular talvez um pouco mais de 292 SHA-512 diferentes para encontrar um SHA-512 com apenas 15 dígitos hexadecimais diferentes.

T

O programa abaixo imprime vários buffers de bytes que tem apenas 14 ou menos dígitos hexadecimais diferentes em seus SHA-512.

import java.security.*;
import java.util.*;

class TesteSHA512 {
    private static char[] hexDigits = "0123456789ABCDEF".toCharArray();
    private static String hex (byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append (hexDigits[(b & 0xF0) >>> 4]).append (hexDigits[b & 0x0F]);
        }
        return sb.toString();
    }
    private static String hexSep (byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append (hexDigits[(b & 0xF0) >>> 4]).append (hexDigits[b & 0x0F]).append (',');
            
        }
        return sb.toString();
    }
    private static int countDistinctDigits (String hex) {
        BitSet bs = new BitSet();
        for (int i = 0; i < hex.length(); ++i) {
            bs.set (hex.charAt (i));
        }
        return bs.cardinality();
    }
    private static String absentDigits (String hex) {
        BitSet bs = new BitSet();
        for (int i = 0; i < hex.length(); ++i) {
            bs.set (hex.charAt (i));
        }
        StringBuilder sbMessage = new StringBuilder();
        sbMessage.append ("The following digits were not found: ");
        for (char ch : "0123456789ABCDEF".toCharArray()) {
            if (!bs.get (ch)) {
                sbMessage.append (ch).append (", ");
            }
        }
        return sbMessage.toString();
    }
    public static void main (String[] args) throws Exception {
        byte[] b = new byte[3];
        byte[] digest;
        MessageDigest md = MessageDigest.getInstance ("SHA-512");
        for (int i = 0; i < 256 * 256 * 256; ++i) {
            b[0] = (byte) ((i >>> 16) & 0xFF);
            b[1] = (byte) ((i >>> 8) & 0xFF);
            b[2] = (byte) (i & 0xFF);
            md.reset();
            digest = md.digest (b);
            String s = hex (digest);
            int count = countDistinctDigits (s);
            if (count < 15) {
                System.out.println ("The buffer [" + hexSep (b) + "] has the following SHA-512 with " + 

count + " distinct digits:");
                System.out.println (s);
                System.out.println (absentDigits (s));
                System.out.println ();
            }
        }
    }
}
A

Galera, era isso mesmo que eu queria saber.

Obrigado pela ajuda!

Criado 7 de janeiro de 2010
Ultima resposta 8 de jan. de 2010
Respostas 7
Participantes 5