Pergunta
É possível gerar curto GUID como no YouTube (N7Et6c9nL9w)?
Como pode ser feito? Quero usá-lo no aplicativo web.
Solução
Você pode usar Base64:
string base64Guid = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
Isso gera uma string como E1HKfn68Pkms5zsZsvKONw==
. Uma vez que um GUID é sempre 128 bits, você pode omitir o ==
que você sabe que vai estar sempre presente no final e que lhe dará uma seqüência de 22 caracteres. Isto não é tão curto quanto YouTube embora.
Outras dicas
9 caracteres não é um Guid. Dado que, você poderia usar a representação hexadecimal de um int, que lhe dá uma seqüência de 8 Char.
Update 1: Não sei por que o acima tem um downvote, mas para qualquer um se perguntando:
Você pode usar um id você já pode ter. Também você pode usar .GetHashCode contra diferentes tipos simples e lá você tem um int diferente. Você também pode XOR campos diferentes. E se você estiver nele, você pode até usar um número aleatório - hey, você tem bem acima 2.000.000.000+ valores possíveis, se você ficar com os pontos positivos;)
Como mencionado na resposta aceita, ele pode fazer problemas se você estiver usando o GUID no URL. Aqui está uma resposta mais completa:
public string ToShortString(Guid guid)
{
var base64Guid = Convert.ToBase64String(guid.ToByteArray());
// Replace URL unfriendly characters with better ones
base64Guid = base64Guid.Replace('+', '-').Replace('/', '_');
// Remove the trailing ==
return base64Guid.Substring(0, base64Guid.Length - 2);
}
public Guid FromShortString(string str)
{
str = str.Replace('_', '/').Replace('-', '+');
var byteArray = Convert.FromBase64String(str + "==");
return new Guid(byteArray);
}
Uso:
var guid = Guid.NewGuid();
var shortStr = ToShortString(guid);
// shortStr will look something like 2LP8GcHr-EC4D__QTizUWw
var guid2 = FromShortString(shortStr);
Assert.AreEqual(guid, guid2);
Como já foi mencionado, VideoId
do YouTube não é tecnicamente um GUID já que não é inerentemente único.
De acordo com Wikipedia :
O número total de chaves únicas é 2 128 ou 3,4 × 10 38 . Este número é tão grande a probabilidade de que o mesmo número a ser gerado aleatoriamente duas vezes é insignificante.
VideoId
A singularidade do YouTube é mantido por seu algoritmo do gerador.
Você pode escrever seu próprio algoritmo, ou você pode usar algum tipo de gerador de seqüência aleatória e utilizar a restrição UNIQUE CONSTRAINT
em SQL para impor a sua singularidade.
Primeiro, crie um UNIQUE CONSTRAINT
em seu banco de dados:
ALTER TABLE MyTable
ADD CONSTRAINT UniqueUrlId
UNIQUE (UrlId);
Então, por exemplo, gerar uma seqüência aleatória (de philipproplesch ):
string shortUrl = System.Web.Security.Membership.GeneratePassword(11, 0);
Se o UrlId
gerado é suficientemente aleatória e suficientemente longo você deve raramente encontram a exceção que é lançada quando SQL encontra um UrlId
duplicado. Nesse caso, você pode facilmente lidar com a exceção em seu aplicativo web.
Tecnicamente não é um Guid. Youtube tem um simples randomizados gerador de string que você provavelmente pode chicotear acima em poucos minutos usando um conjunto de caracteres permitidos e um gerador de números aleatórios.
Pode não ser a melhor solução, mas você pode fazer algo assim:
string shortUrl = System.Web.Security.Membership.GeneratePassword(11, 0);
Este id provavelmente não é exclusivo global. de GUID deve ser globalmente única vez que incluem elementos que não deve ocorrer em qualquer lugar (o endereço MAC da máquina que gera a ID, o tempo a identificação foi gerado, etc.)
Se o que você precisa é um ID que é único dentro de sua aplicação, use uma fonte número - talvez codificar o valor como um número hexadecimal. Toda vez que você precisa de um ID, agarrá-lo da fonte número.
Se você tiver vários servidores alocação de id de, você poderia pegar um intervalo de números (algumas dezenas ou milhares dependendo ids como rapidamente você está alocando) e que deve fazer o trabalho. um número hexadecimal de 8 dígitos lhe dará 4 bilhões de ids -., mas o seu primeiro id de será muito mais curto
Não é um GUID
Deixe-me saltar com o seguinte
Ele usa o TotalMilliseconds
de EPOCH
e um conjunto válido de caracteres.
Isso não vai ser globalmente únicos, mas exclusivo para a instância onde é define
public string YoutubeLikeId()
{
Thread.Sleep(1);//make everything unique while looping
long ticks = (long)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1,0,0,0,0))).TotalMilliseconds;//EPOCH
char[] baseChars = new char[] { '0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x'};
int i = 32;
char[] buffer = new char[i];
int targetBase= baseChars.Length;
do
{
buffer[--i] = baseChars[ticks % targetBase];
ticks = ticks / targetBase;
}
while (ticks > 0);
char[] result = new char[32 - i];
Array.Copy(buffer, i, result, 0, 32 - i);
return new string(result);
}
A saída virá algo como
XOTgBsu
XOTgBtB
XOTgBtR
XOTgBtg
XOTgBtw
XOTgBuE
Update: O mesmo pode ser alcançado a partir Guid
como
var guid = Guid.NewGuid();
guid.ToString("N");
guid.ToString("N").Substring(0,8);
guid.ToString("N").Substring(8,4);
guid.ToString("N").Substring(12,4);
guid.ToString("N").Substring(16,4);
guid.ToString("N").Substring(20,12);
Para uma ecd65132-ab5a-4587-87b8-b875e2fe0f35
Guid que vai dividi-la em pedaços como ecd65132
, ab5a
, 4587
, 87b8
, b875e2fe0f35
Mas eu não posso garantir que ele seja exclusivo sempre.
Update 2: Há também um projeto chamado ShortGuid para obter um GUID
amigável url pode ser Fron convertido / a um Guid
regulares