Algoritmos de identificação

34 respostas
E

Alguém saberia como gerar algoritmos de identificação eficientes? como por exemplo, cnpj… O meu no caso deve ser gerado em modo offline e ser válido.

Eu estava pensando em fazer assim

1113486644093-33

onde a primeira parte seria o tempo em milisegundos e a outra seria um controle para evitar que tenha dois iguais…

o problema é que ficaria um digito meio grande e sempre haveria caracteres em comum, haveria algum jeito de embaralhar os bits?

bom, valeu ai

34 Respostas

renatosilva

Tem o GUID do Windows, mas não sei como funciona.

Exemplo: {F905B251-567A-44C5-A85C-3D73CF9AA771}

cv1

Qualquer sequencia aleatoria (ou ate mesmo sequencial) de numeros funciona, o que importa mesmo eh o seu algoritmo de validacao. O modulo de 11 que o CPF e CNPJ usam sao famosinhos, e implementacoes nao faltam, mas nada te impede de bolar outros. :slight_smile:

T

Qual o seu problema, exatamente?

  • Você quer gerar um número seqüencial único, só que de maneira distribuída (para não ter de usar um sistema que centraliza a geração).
    Neste caso, no número inclua também a localização (como é o caso do próprio CNPJ, onde um dos dígitos indica em que região do Brasil o CNPJ foi gerado).
    É mais fácil de pensar em placas de carro. Se você andou reparando, as placas que começam por A e vão até BFA (se não me engano) são do Paraná. A partir de BFA, e até GKI (se não me engano), são de São Paulo, e assim por diante.
  • Você quer um número totalmente aleatório (como um GUID ou UUID, mas com dígitos de verificação); dessa forma, se o número for suficientemente grande e você usar um bom gerador de números aleatórios, mesmo com geração descentralizada a probabilidade de termos dois números iguais é infinitesimal;
E

Bom, para o prototipo do trabalho creio que nao serah necessario numeros de identificacao de regiao, o q eu preciso fazer é o seguinte: uma identificacao que, de preferencia contenha só números e que sejapossível gerá-la sem acesso à base de dados (em modo off-line), ou seja, sem comparar pra ver se ela já existe e ainda assim ser válida. foi por isso que eu pensei no esquema dos milisegundos… O problema é que eu gostaria de um número que fosse um pouco menor, hehe

renatosilva

Eduardo, acho que um GUID se é aleatório como o thingol disse, é mais confiável que basear-se em milissegundos, mas se você fosse usar mesmo assim, para diminuir o tamanho que tal você contar os milissegundos a partir de uma determinada data acima (bem acima) de 1/1/1970, tipo hoje? Não serve? Não sei se a quantidade de dígitos diminuiria satisfatoriamente.

Esse teu problema eu também fico pensando como fazer mas é difícil. Penso que nesses casos é preciso buscar informações que sejam únicas e jutar tudo num ID. Tipo, dois planetas não podem estar num mesmo espaço (considerando a escala), assim poderíamos usar a posição do planeta, junto com contagem de tempo, como parte de um identificador garantidamente único. É o que imagino. MAC Addreess, FCC ID, endereços IP etc. seriam coisas que para mim serviriam de base.

Você poderia explicar o que exatamente você quer identificar?


Aliás thingol, eu não sabia que o GUID é aleatório, eu achava que não havia nem probabilidade de haver ids iguais, pelo o que eu li por aí.


Desculpe, não posso resistir: o que seria uma sequência sequencial? :lol:

E

Bom, vou passar um link do meu projeto: https://www.labsec.ufsc.br/tiki-index.php?page=ECFV

É um emissor de Cupom Fiscal Virtual, neste casso a ID deveria ser grande o suficiente para suportar o numero de transacoes comerciais realizadas tipo em santa catarina, algo na casa de milhares… bom, se eu usasse os milisegundos começando em uma determinada data, seria muito fácil o tamanho da id aumentar, em tipo um ano, ou ateh menos, enquanto q se eu utilizar os milisegundos baseados em 1970, só em 2322 seria aumentado um dígito. O que em todo caso, gerar um código e que pudesse ter vários tamanhos não seria uma maneira muito boa, a meu ver, o ideal eh ter um tamanho fixo. Eu ainda acrescentei dois dígitos de controle no final, para evitar uma repetição…

O que seria um GUID?

T

Um GUID pode ser gerado usando-se o MAC Address como um de seus componentes, mas hoje em dia o próprio Windows gera um GUID de forma completamente aleatória (sem mostrar o MAC Address de maneira explícita dentro do GUID) devido a problemas de privacidade (você sabe como os americanos são paranóicos, e com certa razão).
É que seria possível você determinar a partir do GUID que máquina gerou o tal do GUID, já que você conhece o MAC Address.

Para o Eduardo:

GUID = Globally Unique Identifier, ou UUID - Universally Unique Identifier - é porque ele é uma string aleatória de 128 bits, e a probabilidade de você ter dois GUIDs iguais, se todos os geradores de números aleatórios usados para gerá-los forem bons, é infinitesimal. Antigamente no GUID era incluído o MAC Address (endereço da placa de rede), que é um número que cada fabricante de placa de rede se compromete a manter único. Tanto é que o início do número do MAC Address indica qual é o código do fabricante - se você lembra de códigos de barras, se o código começa por 789 indica que o produto foi registrado no Brasil.
(Bom, pelo menos em teoria não deveria haver duas placas de rede com o mesmo MAC Address, mas como você sabe, hoje em dia é possível configurar certas placas para ter exatamente o MAC Address desejado, não o inicializado pelo fabricante).

E

OI problema eh que no caso seria uma string, a meu ver ficaria mais fácil para o usuário ter que digitar apenas números, eu pessoalmente não estou gostando de usar Milisegundos, hehe, mas até agora não vi outra alternativa melhor

renatosilva

Bom, difícil. O GUID é um hexadecimal, você pode transformar em dígitos decimais, mas vai ficar ainda maior do que o exemplo que você deu, Eduardo.

Cara e se você formatasse a data da seguinte maneira: yyyymmddhhmmssmmmm (ano, mês, dia, hora, minuto, segundo, milissegundo)? Ficaria com 18 dígitos, mas dá pra encurtar ainda mais, sacou a idéia, transformar os milissegundos em algo mais curto?

Como você vai garantir que os dois dígitos no final garantirão que os IDs não vão se repetir?

renatosilva

Outra coisa, você começando a contar a partir de hoje, você pode preencher com zero para ficar com tamanho fixo. O número de zeros será determinado de acordo com o limite que você deseja (tipo, a aplicação vai existir para sempre?):

00001-99999

Ih!! Acabaram de avisar que tem um fio pegando o fogo aqui, tenho que desligar o computador!!!

louds

Use hashing de alguns dados como IP/MAC/hora com um PRNG não reiniciado, descarta boa parte dos bits e pronto. Aleatorio o suficiente e com pouca colisão.

Mas afinal, qual o problema de usar um contador seqüêncial?

Caso você queira uma seqüência não repetida de números mas que não siga a ordem natural, vai precisar estudar um pouco de teoria dos números e algebra linear para achar um corpo/anel que seja bom.

E

bom, a principio, nao usaremos sequencial pq precisa senao outro usuario pode ter a informacao, já que nao utilizaremos nenhuma senha… este é o motivo… ateh agora o q melhor atendeu as exigencias foi o milisegundos msm… já que dificilmente vc acertaria os milisegundos e ainda os dois digitos de controle no final como eu demonstrei no meu primeiro post :smiley: além de que tem que ser possível gerá-lo em modo off-line, sem acesso à base de dados onde eles serão armazenados :stuck_out_tongue:

renatosilva

Mas Eduardo o que garante que seus dois dígitos de controle não irão falhar?

louds

Usando milisegundos você pode ter repetição se usarem 2 máquinas diferentes com relogios fora de sincronia.

renatosilva

louds:
Usando milisegundos você pode ter repetição se usarem 2 máquinas diferentes com relogios fora de sincronia.

Isso.

velo

E se usar o tempo em milesegundos + o IP da máquina, ou o hashcode do nome da maquina?!

Procura chava HILO (high low) no google… é uma maneira de gerar chaves únicas para o hibernate!

VELO

E

Bom, talvez milisegundos não seja mto confiável mesmo, ainda mais que milhares de chaves serão geradas diariamente, o que não é viável eh que o número a ser digitado seja muito grande, creio que até 15 dígitos é aceitavel. vou dar uma olhada nesse hilo, talvez se utilizássemos alguma operação sobre bits

E

bom, andei pensando e acho que irei utilizar a sugestao do renato de contar os milisegundos a partir de uma data em especifico, assim os números aparentam ser mais “aleatórios”…

Luca

Olá

Quer um conselho? Não faz assim não. Atente para o que o thingol disse e use a dica do louds. O trabalho será o mesmo mas você dormirá muito mais tranquilo.

[]s
Luca

E

Bom, eu pensei um pouco e queria saber se é possível fazer isto: bolar um algoritmo que criasse um número a partir do cnpj, hora em milisegundos(a partir de 1/4) e o inteiro que representa o ip da máquina)… E que também fosse possível extrair estes 3 valores. Não sei se isto é possível, então queria a ajuda de vocês :wink:

renatosilva

Você tem certeza de que um IP com CNPJ num instante de tempo irá te dar um identificador único? E se o IP for de rede local? Bom, se sim (se o identificador será único), acredito que o problema é que com tudo isso junto o seu número vai ficar enorme. Não sei como é CNPJ, mas em relação a IP, você poderia comprimí-lo em 10 dígitos decimais.

Puxa, rapaz, teu caso é complicado mesmo, hein? Se eu fosse você, conectava ao servidor!!!

E

não tem como hehe, a aplicação deve funcionar mesmo fora da internet, aliás, estou começando a achar que vou ter q usar por ex, uma sequencia de caracteres, nao apenas numeros, assim, teriamos mais possibilidades… Mas uma coisa, alguém sabe alguma API do java que pegasse o MAC Address? Por exemplo: xf4qbcag seria a id de identificação

cv1

Ja pensou em usar o servidor como repositorio de ranges? Mais ou menos assim:

Cliente: Ei, servidor, tudo bem? Me arruma uns numeros pra eu usar?
Servidor: Opa, beleza! Voce pode usar 100000 ate 199999 por hoje. Divirta-se!

Outro Cliente: Ei, servidor, me arruma uns numeros tambem?
Servidor: Claro, fica com 200000 ate 299999!

E, no fim do dia, eh soh limpar tudo. Sincronize os relogios direitinho (NTP!) e voce nao vai ter problemas :wink:

E

o problema eh q se no inicio do dia nao tiver conexao com a internet…

renatosilva

Pelo o que o cv falou, só às vezes o programa vai precisar estar em rede. Mas se ele nunca vai poder estar em rede mesmo, essa faixa poderia ser especificada (se der via rede) na instalação do sistema. O que acha Eduardo?

Quanto a usar hexadecimais, se você aceita usar isso mesmo, eu recomendaria usar uma base maior tipo 36 (0-9, A-Z), porque vai comprimir ainda mais os números. Um IP, e inclusive um MAC Address, por exemplo, poderiam ocupar cada um “apenas” 7 dígitos.

Z

Aí é só você reservar um certo range pra esses casos em que não foi possível se comunicar com o servidor. :wink:

Luca

Olá

Com os requisitos pedidos, eu usaria UDDI mesmo. Tá certo, é enorme mas não sou eu que vou conferir mesmo. Ele nem seria mostrado. Todo mundo dormiria mais tranqüilo.

[]s
Luca

velo

Não pode ter um ID na máquina e outro ID no servidor e quando conectar no servidor ele passa os ID dele pra máquinas…

Mas se quiser HiLo, hibernate… http://www.hibernate.org/170.html

VELO

E

bom, eu realmente terei que usar uma base maior, como o renato falou, de 36 msm… Agora, só me digam se é viável isso: gerar um número a partir do inteiro que representa o ip, o cnpj, a hora e o mac address… E seria possível ainda extrair esses´dados do número gerado… Não sei se isso é possível, andei falando com um professor e ele mencionou o Teorema Chinês do Resto, mas eu creio que isso vai muito além do necessário…

louds

Depende do extrair. Qual operação de extração você precisa?

A segunda é mais segura e viavel de implementar

E

no caso teria que ter 4 itens…

q(a, x, y, z, t) = true // verifica q a foi gerado a partir de x, y, z e t

onde x = milisegundos, y = ip, z = mac address e t = cnpj
renatosilva

Para os IPs, disponha os quatro octetos lado a lado em hexa, por exemplo 255.255.255.255 fica assim: FFFFFFFF. Então converta isso de hexa para base 36. O mesmo princípio para o MAC. Creio que com o CNPJ não seja muito diferente, tipo tirar os sinais e transformar de base 10 para 36.

velo

Putz veio, HiLo!!! é o time stamp concatenado com o IP… garantido! O hibernate usa! Nem precisa do mac e/ou do CNPJ, ou troca o IP pelo MAC…

VELO

E

nao irei mais fazer aquilo de criar um numero gerado por outros 4 e extrailos, hehe, iria dar um trabalho danado, alias, se eh que eh possivel :stuck_out_tongue:

Criado 14 de abril de 2005
Ultima resposta 19 de abr. de 2005
Respostas 34
Participantes 8