Come faccio a generare più hash che possono essere risolti in un singolo valore?

1

Ho bisogno di più URL "casuali" che mascherano semplicemente l'URL originale, cioè:

/ABC
/CBA
/CAB

Tutti si risolvono in /6

Mi è capitato di abbinare una lettera a un numero e quindi di sommarle al valore singolo.

A = 1
B = 2
C = 3
...

/ABC = A + B + C = 6
/CBA = C + B + A = 6
/CAB = C + A + B = 6
...

C'è un nome per questo? Non sembra essere hashing reversibile

Esiste un algoritmo esistente per generare + risolverli?

    
posta bfred.it 23.03.2016 - 04:50
fonte

3 risposte

0

L'ho trovato, funziona solo sui numeri (una conversione da stringa a numero potrebbe avvenire all'esterno se necessario).

Converte il numero in binario e quindi esegue il mapping di lettere minuscole che sono dispari (a, c, e, ...) o pari (b, d, f, ...) rispettivamente a 0 o a 1. Quindi

74 =   1001010 =   "baababa"
74 =   1001010 =   "pcgtghy"
74 =  01001010 =  "etcetera"

Questo è il codice in Javascript

const a = 'a'.charCodeAt(0);
const length = 'z'.charCodeAt(0) - a;

function padLeft (string, len){
    while(string.length < len) { string = 0 + string; }
    return string;
}
function decode (val) {
    return (val.charCodeAt(0) - a) % 2;
}
function encode (odd) {
    // generate a random letter in the available range
    // but make sure it's odd or even
    return String.fromCharCode(a + Math.floor(length * Math.random() / 2) * 2 + parseInt(odd, 10));
}
function generate (number, minLength = 0) {
    return padLeft(number.toString(2), minLength).split('').map(encode).join('');
}
function solve (code) {
    return parseInt(code.split('').map(decode).join(''), 2);
}

E questo è l'utilizzo, accetta anche un parametro di lunghezza minima

code = generate(74);     console.log(code, solve(code));
code = generate(74, 5);  console.log(code, solve(code));
code = generate(74, 10); console.log(code, solve(code));
code = generate(74, 20); console.log(code, solve(code));

Anche su npm

    
risposta data 23.03.2016 - 06:35
fonte
2

Come sottolineato dagli altri commentatori, non si sta davvero cercando una funzione di hash, ma invece serve solo una semplice crittografia. Come dichiari che le banali violazioni della sicurezza non hanno alcuna conseguenza, puoi contare su cifrature di sostituzione molto semplici. Sembrerà incomprensibile, ma funziona ancora bene.

Il nome che più si avvicina a una cosa del genere è la generazione di testi cifrati in crittografia. "Cifrario" significa semplicemente quel non verboso illeggibile che si ottiene dopo aver crittografato il tuo prezioso testo con una chiave segreta. Nel tuo caso, dal momento che desideri solo quella cifra, puoi semplicemente includere la chiave, suddividere banalmente la crittografia e per la tua interpretazione, basta estrarre la chiave e decifrare la parte rimanente, che sarebbe il codice.

Si noti che questo approccio combinato con una codifica alfanumerica come BASE64 può essere applicato con quasi tutti gli algoritmi di crittografia che si desiderano. Roll your own (fattibile, dal momento che non ne hai bisogno per essere effettivamente al sicuro), o prendere un'implementazione standard molto strong di qualcosa come AES. Non ha molta importanza.

Ecco un esempio: supponiamo che tu voglia utilizzare i caratteri AZ e tu esegui una cifra di rotazione (come ROT -13), tale che il primo carattere sia la "chiave". Puoi prendere qualsiasi parola-URL come "DATA" e ruotarla basandosi su un primo carattere aggiuntivo. Interpretiamo A come 0, quindi B è una rotazione di 1, quindi D diventerebbe la lettera E (una dopo D), A diventa B e così via. Il carattere Z diventa nuovamente A tramite una semplice operazione modulo.

Questo ti dà immediatamente 25 diverse varianti di "DATA" che sembrano "personalizzate" ma "inintelligibili". Qualcosa del genere:

AEBUB BFCVC ...

    
risposta data 23.03.2016 - 13:14
fonte
0

Se utilizzi l'hashing, potrebbe essere necessario un dizionario per risolvere un URL con hash su un normale URL; per es.

Dictionary<int, Uri> urlHashes;

Così puoi fare:

Uri originalURL = urlHashes[hashKey];

Altrimenti dovrai controllare l'hash ricevuto contro ogni URL esistente nel tuo ambito; per esempio:.

List<Uri> allUrls;
foreach (Uri u in allUrls)
{
     int hash = u.GetHashCode();
     if (hash == hashKey)
     {
         return u;
     }
}
throw new InvallidUrl()

Ci sono due opzioni per creare più chiavi che puntano allo stesso URL:

  1. Aggiungi un numero casuale o una stringa all'URL e calcola l'hash sulla combinazione; per esempio:.

    const int mySecretRandomPrime = 3943;
    int randomNumber = new Random().Next(1000);
    int urlHash = (url.GetHashCode() * mySecretRandomPrime) + randomNumber;
    
    return urlHash;
    

    Se archivi le coppie di chiavi-URL, puoi cercare l'URL originale tramite l'hash composito che hai memorizzato.

    Oppure, se non memorizzi tutti gli hash url forniti, puoi richiedere al client di inviare sia la combinazione urlHash che randomBumber e puoi scorrere l'elenco degli URL noti, calcolare l'hash combinato e restituire l'URL corrispondente; per esempio:.

    List<Uri> allUrls;
    const int mySecretRandomPrime = 3943;
    
    foreach (Uri u in allUrls)
    {
        int hash = (url.GetHashCode() * mySecretRandomPrime) + randomNumber;
        if (hash == hashKey)
        {
            return u;
        }
    }
    throw new InvallidUrl()
    
  2. Se scegli di archiviare coppie chiave-url, puoi anche lasciare completamente gli hash degli URL e solo restituire (crittograficamente) GUID / UUID casuali.

risposta data 23.03.2016 - 14:18
fonte

Leggi altre domande sui tag