Em nosso aplicativo, estamos criando arquivos Xml com um atributo que possui um valor Guid. Esse valor precisava ser consistente entre as atualizações de arquivo. Portanto, mesmo que tudo o mais no arquivo seja alterado, o valor guid para o atributo deve permanecer o mesmo.
Uma solução óbvia era criar um dicionário estático com o nome do arquivo e os Guids a serem usados para eles. Então, sempre que geramos o arquivo, procuramos o nome do arquivo no dicionário e usamos o guid correspondente. Mas isso não é viável porque podemos escalar para centenas de arquivos e não queremos manter uma grande lista de guias.
Portanto, outra abordagem era tornar o Guid o mesmo com base no caminho do arquivo. Visto que nossos caminhos de arquivo e estrutura de diretório de aplicativo são exclusivos, o Guid deve ser exclusivo para esse caminho. Portanto, cada vez que executamos uma atualização, o arquivo obtém o mesmo guid com base em seu caminho. Eu encontrei uma maneira legal de gerar esses ' Guias Determinísticos ' (Obrigado Elton Stoneman). Basicamente, ele faz isso:
private Guid GetDeterministicGuid(string input)
{
//use MD5 hash to get a 16-byte hash of the string:
MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
byte[] inputBytes = Encoding.Default.GetBytes(input);
byte[] hashBytes = provider.ComputeHash(inputBytes);
//generate a guid from the hash:
Guid hashGuid = new Guid(hashBytes);
return hashGuid;
}
Assim, dada uma string, o Guid será sempre o mesmo.
Existem outras abordagens ou maneiras recomendadas de fazer isso? Quais são os prós ou contras desse método?
Isso irá converter qualquer string em um Guid sem ter que importar um assembly externo.
Existem maneiras muito melhores de gerar um Guid exclusivo, mas esta é uma maneira de atualizar consistentemente uma chave de dados de string para uma chave de dados Guid.
fonte
Como Rob menciona, seu método não gera um UUID, ele gera um hash que se parece com um UUID.
O RFC 4122 em UUIDs permite especificamente UUIDs determinísticos (baseados em nome) - as versões 3 e 5 usam md5 e SHA1 (respectivamente). A maioria das pessoas provavelmente está familiarizada com a versão 4, que é aleatória. A Wikipedia oferece uma boa visão geral das versões. (Observe que o uso da palavra 'versão' aqui parece descrever um 'tipo' de UUID - a versão 5 não substitui a versão 4).
Parece haver algumas bibliotecas por aí para gerar UUIDs de versão 3/5, incluindo o módulo uuid python , boost.uuid (C ++) e OSSP UUID . (Não procurei nenhum .net)
fonte
Você precisa fazer uma distinção entre as instâncias da classe
Guid
e os identificadores que são globalmente exclusivos. Um "guid determinístico" é na verdade um hash (conforme evidenciado por sua chamada paraprovider.ComputeHash
). Hashes têm uma chance muito maior de colisões (duas strings diferentes produzindo o mesmo hash) do que o Guid criado viaGuid.NewGuid
.Portanto, o problema com sua abordagem é que você terá que estar ok com a possibilidade de que dois caminhos diferentes produzirão o mesmo GUID. Se você precisar de um identificador exclusivo para qualquer string de caminho, a coisa mais fácil a fazer é apenas usar a string . Se você precisa que a string seja ocultada de seus usuários, criptografe-a - você pode usar ROT13 ou algo mais poderoso ...
A tentativa de encaixar algo que não é um GUID puro no tipo de dados GUID pode levar a problemas de manutenção no futuro ...
fonte
MD5 é fraco, acredito que você pode fazer a mesma coisa com SHA-1 e obter melhores resultados.
BTW, apenas uma opinião pessoal, vestir um hash md5 como um GUID não o torna um bom GUID. Os GUIDs, por sua própria natureza, são não determinísticos. isso parece uma trapaça. Por que não chamar um spade de spade e apenas dizer que é uma string renderizada como hash da entrada. você pode fazer isso usando esta linha, em vez da nova linha de guid:
fonte
Guid
objeto?