Pergunta

Estou interessado em criar links de minúsculo URL. Minha idéia era simplesmente armazenar um identificador incrementador para cada URL longo postado e depois converter este ID em sua variante base 36, como o seguinte no PHP:

$tinyurl = base_convert($id, 10, 36)

O problema aqui é que o resultado é adivinhável, embora seja difícil adivinhar qual será o próximo URL, enquanto ainda será curto (minúsculo). Por exemplo. ATM Se meu último tinyurl foi A1, o próximo será A2. Isso é uma coisa ruim para mim.

Então, como eu garantiria que o pequeno URL resultante não seja tão adivinhável, mas ainda curto?

Foi útil?

Solução

O que você está pedindo é um equilíbrio entre a redução de informações (URLs para seus índices no seu banco de dados) e aumento artificial de informações (para criar orifícios em sua sequência).

Você tem que decidir o quão importante é ambos para você. Outra pergunta é se você simplesmente não deseja que os URLs seqüenciais sejam adivinhados ou os tem suficientemente aleatórios para fazer adivinhar algum URL válido difícil.

Basicamente, você deseja declarar n de n IDs válidos. Escolha N menor para tornar os URLs mais curtos e diminua N para gerar URLs difíceis de adivinhar. Torne n e n maior para gerar mais URLs quando os mais curtos forem levados.

Para atribuir os IDs, você pode usar qualquer tipo de função de gerador ou hash aleatória e capturá -lo ao seu alcance de destino N. Se você detectar uma colisão, escolha o próximo valor aleatório. Se você atingiu uma contagem de n IDs exclusivos, deve aumentar o intervalo do seu conjunto de identificação (n e n).

Outras dicas

Eu simplesmente faria CRC32 URL

$url = 'http://www.google.com';
$tinyurl = hash('crc32', $url ); // db85f073

Contras: Constant 8 caracteres identificador longo

Isso é realmente barato, mas se o usuário não souber que está acontecendo, não é tão adivinhável, mas prefixo e poste o ID real com 2 ou 3 números/letras aleatórias.

Se eu visse 9d2a1me3, não imaginaria que o DM2A2DQ2 fosse o próximo da série.

Tente xor'ing o $ id com algum valor, por exemplo $id ^ 46418 - e para converter de volta ao seu ID original, você apenas executa o mesmo xor novamente $mungedId ^ 46418. Empilhe isso com o seu Base_convert e talvez alguma troca de chars na corda resultante e será bastante complicado adivinhar um URL.

Outra maneira seria definir o número máximo de caracteres para o URL (digamos que é n). Você pode escolher um número aleatório entre 1 e n!, Qual seria o seu número de permutação.

Em qual novo URL, você aumentaria o ID e usaria o número de permutação para associar o ID real que seria usado. Finalmente, você basearia 32 (ou qualquer outra coisa) codificar seu URL. Isso seria perfeitamente aleatório e perfeitamente reversível.

Se você deseja uma função injetiva, pode usar qualquer forma de criptografia. Por exemplo:

<?php
$key = "my secret";
$enc = mcrypt_ecb (MCRYPT_3DES, $key, "42", MCRYPT_ENCRYPT);
$f = unpack("H*", $enc);
$value = reset($f);
var_dump($value); //string(16) "1399e6a37a6e9870"

Reverter:

$rf = pack("H*", $value);
$dec = rtrim(mcrypt_ecb (MCRYPT_3DES, $key, $rf, MCRYPT_DECRYPT), "\x00");
var_dump($dec); //string(2) "42"

Isso não lhe dará um número na base 32; Ele fornecerá os dados criptografados com cada byte convertido na base 16 (ou seja, a conversão é global). Se você realmente precisar, pode convertê -lo trivialmente na base 10 e depois para a base 32 com qualquer biblioteca que suporta grandes números inteiros.

Você pode predefinir os códigos de 4 caracteres com antecedência (todas as combinações possíveis) e, em seguida, randomizam essa lista e armazená-lo nesta ordem aleatória em uma tabela de dados. Quando você quiser um novo valor, pegue o primeiro da parte superior e remova -o da lista. É rápido, sem cálculo na fly-fly e garante pseudo-randomidade ao usuário final.

Hashids é uma biblioteca de código aberto que gera IDs curtos, únicos, não sequenciais, semelhantes ao YouTube de um ou muitos números. Você pode pensar nisso como um algoritmo para ofuscar números.

Ele converte números como 347 em cordas como "yr8" ou matriz como [27, 986] em "3ktmd". Você também pode decodificar esses IDs de volta. Isso é útil para agrupar vários parâmetros em um ou simplesmente usá -los como UIDs curtos.

Use -o quando você não quer para expor Seu banco de dados ids para o usuário.

Ele permite o alfabeto personalizado e o sal, portanto, os IDs são únicos apenas para você.

A entrada incremental é mutilada para permanecer inocente.

Não há colisões porque o método é baseado no número inteiro de conversão hexadecimal.

Foi escrito com a intenção de colocar IDs criados em lugares visíveis, como o URL. Portanto, o algoritmo evita gerar palavras de maldição em inglês mais comuns.

Exemplo de código

$hashids = new Hashids();
$id = $hashids->encode(1, 2, 3); // o2fXhV
$numbers = $hashids->decode($id); // [1, 2, 3]

Acabei criando uma soma MD5 do identificador, usei os 4 primeiros alfanuméricos dele e se essa for uma duplicata, simplesmente incrementam o comprimento até que não seja mais uma duplicata.

function idToTinyurl($id) {
    $md5 = md5($id);
    for ($i = 4; $i < strlen($md5); $i++) {
        $possibleTinyurl = substr($md5, 0, $i);
        $res = mysql_query("SELECT id FROM tabke WHERE tinyurl='".$possibleTinyurl."' LIMIT 1");
        if (mysql_num_rows($res) == 0) return $possibleTinyurl;
    }
    return $md5;
}

Aceitaram a resposta da RELET, pois me levou a essa estratégia.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top