|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
[C] Convertire un file in un numero intero
Salve a tutti,
come da oggetto vorrei poter convertire un file qualsiasi in un numero intero. Per la trattazione degli interi utilizzo la libreria GMP, quindi posso trattare interi molto grandi. Qualcuno se la cosa sia fattibile? |
|
|
|
|
|
#2 |
|
Member
Iscritto dal: Sep 2008
Città: Milano
Messaggi: 126
|
Un file è una sequenze ordinata di bit quindi è già un numero (tipicamente enorme) espresso in base 2... tuttavia quello che credo tu stia cercando è una funzione hash.
ciao! british |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
Ultima modifica di tuccio` : 19-11-2010 alle 12:39. |
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
Quote:
Non voglio calcolare alcuna funzione di Hash, né SHA1, né MD5, che servono a tutt'altro. Mi serve sapere il file X corrisponde al numero Y. Stop. Mi serve un intero enorme, OK, anche in binario, ma posso (credo) sempre convertirlo in intero. Grazie mille. |
|
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2780
|
Ho dato un'occhiata alla libreria GMP, visto che può trattare numeri arbitrariamente grandi si può fare a patto che la memoria sia sufficiente (quindi potrai ottenere un numero solo per file abbastanza piccoli).
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: May 2001
Messaggi: 12869
|
Onestamente mi sembra un po' una follia. Il numero che cerchi potrebbe essere generato appunto dalla concatenazione dei numeri ASCII che rappresentano le lettere, il punto è che la grandezza di questo numero dipende strettamente dalla lunghezza della stringa.
Già una stringa di 80 caratteri vorrebbe dire mediamente un numero con 160 cifre, che è un NUMERO ENORME, immagina un file di qualche megabyte (1 milione di caratteri significherebbe un numero con in media 2 milioni di cifre). Un hash SHA1 è un numero a 160bit, ovvero 20bytes, sai che la lunghezza sarà sempre quella e che la probabilità di collisione è comunque molto bassa. Quindi un hash SHA1 in realtà è proprio quello che cerchi, per definizione di funzione di hash. Poi bisognerebbe vedere esattamente cosa ci vorresti fare. |
|
|
|
|
|
#7 | ||
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
Quote:
Lo so. Infatti detta così, non può sembrare altro che una follia, ma per scopi di ricerca, devo provare a crittografare dei file con la Homomorphic Encryption usando una libreria che però tratta interi. Questo tipo di crittografia ha alcune proprietà che a me interessano, e vorrei sfruttarle sui file. Quote:
Ecco perché dell'hash non me ne faccio nulla. O almeno credo, dal momento che facendo l'hash di un file, il risultato è una "stringa" ma rispetto al file ho perso informazioni, e non posso recuperare il file originario dato l'hash. |
||
|
|
|
|
|
#8 | |
|
Senior Member
Iscritto dal: May 2001
Messaggi: 12869
|
Quote:
Chiaramente l'hash non è reversibile (quantomeno facilmente). Comunque stavo pensando che potresti ridurre di molto i dati (specialmente se parliamo di testo) usando qualche libreria per la compressione prima di calcolare il numero. Potresti fare quanto segue: - applichi un algoritmo di compressione a tua scelta - calcoli la sequenza di caratteri ascii associata al file compresso e tiri fuori un numero relativemente grosso a quel punto per tornare indietro basterebbe: - ricreare il file compresso a partire dal numero - decomprimere il file risultante Una nota: sarebbe auspicabile normalizzare i codici ASCII così che siano tutti della stessa lunghezza. Cerco di spiegarmi: come saprai l'ASCII standard prevede i caratteri dallo 0 al 126. Questo significa che se ti trovi davanti a 2 caratteri (32 e 107 per esempio) quando costruisci il numero otterresti 32107. Questo numero chiaramente può essere interpretato in diversi modi, ad esempio potrei associarlo ai caratteri 32, 10, 7 oppure a 3, 21, 07 e così via... Per cui dovresti cercare di normalizzarli affinché il numero più alto e quello più basso che vuoi rappresentare siano di dimensione fissa, ad esempio se decidi di farli di 2 cifre bisognerebbe farli rientrare in un intervallo tra 10 e 99 (ovvero 89 caratteri utili, quindi hai delle limitazioni). Usando sequenze di 3 numeri potresti mappare tutti i caratteri, tuttavia già solo con stringhe di 2 caratteri ti troveresti un numero con 6 cifre. Ribadisco che ci vuole poco affinché una cosa del genere diventi ingestibile. Ultima modifica di WarDuck : 19-11-2010 alle 17:52. |
|
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
WarDuck: grazie. Oltre che estremamente chiaro, sei stato molto gentile. Apprezzo molto la tua risposta.
Quando parlavo di "stringa" (messa a posta tra virgolette), intendevo una quantità generica, ma hai fatto bene a puntualizzare. La tua soluzione andrebbe anche bene, ma purtroppo non posso utilizzarla, perché lo scopo è quello di trattare qualsiasi tipo di file. Auspicabilmente di qualsiasi dimensione (entro certi limiti, ovviamente). Il tuo post mi ha chiarito molte cose, e credo che dovrò riflettere bene sul da farsi perché quello che avevo in mente di fare comincia ad essere un po' problematico. Grazie molte. |
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
Scusa, mi stavo rifacendo un attimo due calcoli.
Tu hai scritto che "Già una stringa di 80 caratteri vorrebbe dire mediamente un numero con 160 cifre". Verissimo che hai detto "mediamente", ma volevo confrontarmi per vedere se i calcoli che ho fatto io siano giusti. 1 char = 1 byte = 8 bit 80 caratteri => 80x8 = 640bit Quindi il numero massimo rappresentabile è 2^640 -1, ovvero circa 4*10^192, ovvero, 4 seguito da 192 zeri. Quindi un numero da 193 cifre. Giusto? |
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: Feb 2010
Messaggi: 466
|
Quote:
__________________
I robot hanno scintillanti fondoschiena metallici che non dovrebbero essere baciati. |
|
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
Grazie per la conferma!
|
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: May 2001
Messaggi: 12869
|
Mmm sarà l'ora ma non ho ben capito cosa intendiate...
Se ho una stringa tipo "ABCD", sono 4 byte, ovvero 4 caratteri. Se ogni carattere ASCII lo rappresentassimo con 2 cifre (perché ad esempio abbiamo scelto di usare i numeri da 10 a 99), abbiamo un numero i cui simboli o cifre sono 8, ovvero il doppio. Esempio: A = 10 B = 11 C = 12 D = 13 ABCD (4 cifre) = 10111213 (8 cifre) Per cifre intendo le cifre con cui viene rappresentato graficamente, non come viene rappresentato nel calcolatore, forse voi intendevate quest'ultima cosa? |
|
|
|
|
|
#14 | |
|
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2780
|
Quote:
Ad ogni modo se consideri un file come una stringa di testo o come un intero il numero di bit che ti serve per rappresentare l'uno o l'altro non cambia. Non so come GMP rappresenti internamente gli interi ma meglio di così non può fare senza perdere informazioni (a meno che non comprima i dati ma ne dubito). Quindi quando dicevo che non potrai ottenere numeri da file troppo grandi intendevo dire che c'è un limite fisico che è quello della memoria. |
|
|
|
|
|
|
#15 | |
|
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
Quote:
il problema è che se piglia un array di int e il file non è di dimensione multipla della dimensione del tipo int è un casino :/ |
|
|
|
|
|
|
#16 | ||
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
Sì sì, io intendevo proprio quello, ovvero data la rappresentazione binaria su disco di quel file, ottengo l'intero.
La soluzione ASCII la devo per forza scartare, nel mio caso. Si tratta di interi a precisione multipla ed il tipo di dato è un mpz_t, ed ecco la parte di codice in questione nel file /usr/include/gmp.h: Codice:
typedef struct
{
int _mp_alloc; /* Number of *limbs* allocated and pointed
to by the _mp_d field. */
int _mp_size; /* abs(_mp_size) is the number of limbs the
last field points to. If _mp_size is
negative this is a negative number. */
mp_limb_t *_mp_d; /* Pointer to the limbs. */
} __mpz_struct;
#endif /* __GNU_MP__ */
typedef __mpz_struct MP_INT; /* gmp 1 source compatibility */
typedef __mpz_struct mpz_t[1];
Quote:
Sì, si chiama libpaillier, e funziona molto bene (provando con numeri interi). Quote:
Codice:
/* Allocate and initialize a paillier_plaintext_t from an unsigned long integer, an array of bytes, or a null terminated string. */ paillier_plaintext_t* paillier_plaintext_from_ui( unsigned long int x ); paillier_plaintext_t* paillier_plaintext_from_bytes( void* m, int len ); paillier_plaintext_t* paillier_plaintext_from_str( char* str ); |
||
|
|
|
|
|
#17 |
|
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
probabilmente è più efficiente usare la versione long, perché hai 1/8 dei numeri.. però ti costringerebbe a fare un lavoro sui file.. e per file che superano la memoria messa a disposizione dall'os dovresti anche inventarti qualcosa per non tenere tutto in ram
con il mapping l'os fa tutto da solo ps: dovresti usare la versione che prende void* non quella che prende char* Ultima modifica di tuccio` : 20-11-2010 alle 10:01. |
|
|
|
|
|
#18 |
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
OK, grazie, ora mi metto a fare delle prove.
|
|
|
|
|
|
#19 |
|
Senior Member
Iscritto dal: Jan 2004
Città: ROMA
Messaggi: 2055
|
Confermo quanto detto fin'ora. Anche trasformando un file di pochi byte in un void*, il tipo di dato mpz, non riesce a contenere un intero corrispondente al contenuto del file:
gmp: overflow in mpz type Aborted |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 13:19.





















