Newsgroup: it.comp.os.linux.development
Titolo: da steringa a identificatore univoco

Salve a tutti.
Conoscete qualche funzione o libreria che (da un programma scritto in 
C), data una stringa, ne ritorni un identificatore numerico univoco ?
Una cosa tipo:
int newID = makeUnieID("pippoplutopaperino");
Grazie inifnite

 
l'algoritmo md5 (conosciuto come checksum)

 Grazie inifnite
Premesso che una stringa puo' avere ordinalita' maggiore di un intero
e quindi piu' stringhe possono collidere allo stesso ID di tipo int,
valuta una funzione di hash, magari di quelle con proprieta' crittografiche
come MD5, di cui puoi utilizzare una solo word. Se il calcolo di MD5 e'
considerato troppo "costoso", puoi valutare CRC32 dato che non ti interessa
la non falsabilita'.
o anche alcune funzioni di hash per accesso ad hash table che puoi
scegliere per esempio qui:
http://burtleburtle.net/bob/hash/doobs.html
Ciao
Roberto
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

AlterX ha scritto:

Ma e' univoco ?
oppure c'e' una qualche possibilita' che vi siano valori uguali ?
Grazie
Ciao

 oppure c'e' una qualche possibilita' che vi siano valori uguali ?
Nessun algoritmo (che io immagini) genera univocità se una stringa ha la 
stessa lunghezza e gli stessi caratteri!!!

> int newID = makeUnieID("pippoplutopaperino");
ma tu vuoi che a stessa stringa di inpput corrisponda stesso id, o no?
nel primo caso, crc o md5 come ti hanno gia' detto.
nel secondo (ma giuro che non ne vedo il senso) gli associ lo unixtime :)
Red

 
http://burtleburtle.net/bob/hash/doobs.html
Grazie, ci guardo
Ciao

AlterX ha scritto:

Okay, ovvio che la stringa "ciao" otterra' sempre lo stesso ID ad ogni 
applicazione della funzione, ma la cosa che serve e' che nessun'altra 
stringa diversa da "ciao" possa avere un ID uguale a quello di "ciao".
hem , ciao :)

 ma tu vuoi che a stessa stringa di inpput corrisponda stesso id, o no?
Yes ;)
Pero' vorrei avere "certezza" che per il valore di stringa sia univoco.
Cioe', che la stringa "pippo" ottenga un ID tutto suo, e che non possa 
essere in un qualche modo duplicato da una stringa differente da "pippo".
Ciao

 Pero' vorrei avere "certezza" che per il valore di stringa sia univoco.
questo non è fisicamente possibile, se devi (e devi) dare un limite di
occupazione di memoria per l'identificatore.
pero' puoi star certo che per l'uso che ne farai, l'md5 è piu' che
sufficiente.
Red

, 1995.
 *
 *
 * June 29, 2001        Manuel Novoa III
 *
 * Added MD5SUM_SIZE_VS_SPEED configuration option.
 *
 * Current valid values, with data from my system for comparison, are:
 *   (using uClibc and running on linux-2.4.4.tar.bz2)
 *                     user times (sec)  text size (386)
 *     0 (fastest)         1.1                6144
 *     1                   1.4                5392
 *     2                   3.0                5088
 *     3 (smallest)        5.1                4912
 */
# define MD5SUM_SIZE_VS_SPEED 2
/* Handle endian-ness */
# if __BYTE_ORDER == __LITTLE_ENDIAN
#  define SWAP(n) (n)
# elif defined(bswap_32)
#  define SWAP(n) bswap_32(n)
# else
#  define SWAP(n) ((n << 24) | ((n&65280)<<8) | ((n&16711680)>>8) | (n>>24))
# endif
# if MD5SUM_SIZE_VS_SPEED == 0
/* This array contains the bytes used to pad the buffer to the next
   64-byte boundary.  (RFC 1321, 3.1: Step 1)  */
static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */  };
# endif	/* MD5SUM_SIZE_VS_SPEED == 0 */
/* Structure to save state of computation between the single steps.  */
struct md5_ctx_t {
	uint32_t A;
	uint32_t B;
	uint32_t C;
	uint32_t D;
	uint32_t total[2];
	uint32_t buflen;
	char buffer[128];
};
/* Initialize structure containing state of computation.
 * (RFC 1321, 3.3: Step 3)
 */
static void md5_begin(struct md5_ctx_t *ctx)
{
	ctx->A = 0x67452301;
	ctx->B = 0xefcdab89;
	ctx->C = 0x98badcfe;
	ctx->D = 0x10325476;
	ctx->total[0] = ctx->total[1] = 0;
	ctx->buflen = 0;
}
/* These are the four functions used in the four steps of the MD5 algorithm
 * and defined in the RFC 1321.  The first function is a little bit optimized
 * (as found in Colin Plumbs public domain implementation).
 * #define FF(b, c, d) ((b & c) | (~b & d))
 */
# define FF(b, c, d) (d ^ (b & (c ^ d)))
# define FG(b, c, d) FF (d, b, c)
# define FH(b, c, d) (b ^ c ^ d)
# define FI(b, c, d) (c ^ (b | ~d))
/* Starting with the result of former calls of this function (or the
 * initialization function update the context for the next LEN bytes
 * starting at BUFFER.
 * It is necessary that LEN is a multiple of 64!!!
 */
static void md5_hash_block(const void *buffer, size_t len, struct md5_ctx_t *ctx)
{
	uint32_t correct_words[16];
	const uint32_t *words = buffer;
	size_t nwords = len / sizeof(uint32_t);
	const uint32_t *endp = words + nwords;
# if MD5SUM_SIZE_VS_SPEED > 0
	static const uint32_t C_array[] = {
		/* round 1 */
		0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
		0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
		0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
		0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
		/* round 2 */
		0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
		0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
		0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
		0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
		/* round 3 */
		0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
		0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
		0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
		0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
		/* round 4 */
		0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
		0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
		0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
		0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
	};
	static const char P_array[] = {
#  if MD5SUM_SIZE_VS_SPEED > 1
		0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,	/* 1 */
#  endif	/* MD5SUM_SIZE_VS_SPEED > 1 */
		1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12,	/* 2 */
		5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2,	/* 3 */
		0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9	/* 4 */
	};
#  if MD5SUM_SIZE_VS_SPEED > 1
	static const char S_array[] = {
		7, 12, 17, 22,
		5, 9, 14, 20,
		4, 11, 16, 23,
		6, 10, 15, 21
	};
#  endif	/* MD5SUM_SIZE_VS_SPEED > 1 */
# endif
	uint32_t A = ctx->A;
	uint32_t B = ctx->B;
	uint32_t C = ctx->C;
	uint32_t D = ctx->D;
	/* First increment the byte count.  RFC 1321 specifies the possible
	   length of the file up to 2^64 bits.  Here we only compute the
	   number of bytes.  Do a double word increment.  */
	ctx->total[0] += len;
	if (ctx->total[0] < len)
		++ctx->total[1];
	/* Process all bytes in the buffer with 64 bytes in each round of
	   the loop.  */
	while (words < endp) {
		uint32_t *cwp = correct_words;
		uint32_t A_save = A;
		uint32_t B_save = B;
		uint32_t C_save = C;
		uint32_t D_save = D;
# if MD5SUM_SIZE_VS_SPEED > 1
#  define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
		const uint32_t *pc;
		const char *pp;
		const char *ps;
		int i;
		uint32_t temp;
		for (i = 0; i < 16; i++) {
			cwp[i] = SWAP(words[i]);
		}
		words += 16;
#  if MD5SUM_SIZE_VS_SPEED > 2
		pc = C_array;
		pp = P_array;
		ps = S_array - 4;
		for (i = 0; i < 64; i++) {
			if ((i & 0x0f) == 0)
				ps += 4;
			temp = A;
			switch (i >> 4) {
			case 0:
				temp += FF(B, C, D);
				break;
			case 1:
				temp += FG(B, C, D);
				break;
			case 2:
				temp += FH(B, C, D);
				break;
			case 3:
				temp += FI(B, C, D);
			}
			temp += cwp[(int) (*pp++)] + *pc++;
			CYCLIC(temp, ps[i & 3]);
			temp += B;
			A = D;
			D = C;
			C = B;
			B = temp;
		}
#  else
		pc = C_array;
		pp = P_array;
		ps = S_array;
		for (i = 0; i < 16; i++) {
			temp = A + FF(B, C, D) + cwp[(int) (*pp++)] + *pc++;
			CYCLIC(temp, ps[i & 3]);
			temp += B;
			A = D;
			D = C;
			C = B;
			B = temp;
		}
		ps += 4;
		for (i = 0; i < 16; i++) {
			temp = A + FG(B, C, D) + cwp[(int) (*pp++)] + *pc++;
			CYCLIC(temp, ps[i & 3]);
			temp += B;
			A = D;
			D = C;
			C = B;
			B = temp;
		}
		ps += 4;
		for (i = 0; i < 16; i++) {
			temp = A + FH(B, C, D) + cwp[(int) (*pp++)] + *pc++;
			CYCLIC(temp, ps[i & 3]);
			temp += B;
			A = D;
			D = C;
			C = B;
			B = temp;
		}
		ps += 4;
		for (i = 0; i < 16; i++) {
			temp = A + FI(B, C, D) + cwp[(int) (*pp++)] + *pc++;
			CYCLIC(temp, ps[i & 3]);
			temp += B;
			A = D;
			D = C;
			C = B;
			B = temp;
		}
#  endif	/* MD5SUM_SIZE_VS_SPEED > 2 */
# else
		/* First round: using the given function, the context and a constant
		   the next context is computed.  Because the algorithms processing
		   unit is a 32-bit word and it is determined to work on words in
		   little endian byte order we perhaps have to change the byte order
		   before the computation.  To reduce the work for the next steps
		   we store the swapped words in the array CORRECT_WORDS.  */
#  define OP(a, b, c, d, s, T)	\
      do	\
        {	\
	  a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T;	\
	  ++words;	\
	  CYCLIC (a, s);	\
	  a += b;	\
        }	\
      while (0)
		/* It is unfortunate that C does not provide an operator for
		   cyclic rotation.  Hope the C compiler is smart enough.  */
		/* gcc 2.95.4 seems to be --aaronl */
#  define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
		/* Before we start, one word to the strange constants.
		   They are defined in RFC 1321 as
		   T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
		 */
#  if MD5SUM_SIZE_VS_SPEED == 1
		const uint32_t *pc;
		const char *pp;
		int i;
#  endif	/* MD5SUM_SIZE_VS_SPEED */
		/* Round 1.  */
#  if MD5SUM_SIZE_VS_SPEED == 1
		pc = C_array;
		for (i = 0; i < 4; i++) {
			OP(A, B, C, D, 7, *pc++);
			OP(D, A, B, C, 12, *pc++);
			OP(C, D, A, B, 17, *pc++);
			OP(B, C, D, A, 22, *pc++);
		}
#  else
		OP(A, B, C, D, 7, 0xd76aa478);
		OP(D, A, B, C, 12, 0xe8c7b756);
		OP(C, D, A, B, 17, 0x242070db);
		OP(B, C, D, A, 22, 0xc1bdceee);
		OP(A, B, C, D, 7, 0xf57c0faf);
		OP(D, A, B, C, 12, 0x4787c62a);
		OP(C, D, A, B, 17, 0xa8304613);
		OP(B, C, D, A, 22, 0xfd469501);
		OP(A, B, C, D, 7, 0x698098d8);
		OP(D, A, B, C, 12, 0x8b44f7af);
		OP(C, D, A, B, 17, 0xffff5bb1);
		OP(B, C, D, A, 22, 0x895cd7be);
		OP(A, B, C, D, 7, 0x6b901122);
		OP(D, A, B, C, 12, 0xfd987193);
		OP(C, D, A, B, 17, 0xa679438e);
		OP(B, C, D, A, 22, 0x49b40821);
#  endif	/* MD5SUM_SIZE_VS_SPEED == 1 */
		/* For the second to fourth round we have the possibly swapped words
		   in CORRECT_WORDS.  Redefine the macro to take an additional first
		   argument specifying the function to use.  */
#  undef OP
#  define OP(f, a, b, c, d, k, s, T)	\
      do	\
	{	\
	  a += f (b, c, d) + correct_words[k] + T;	\
	  CYCLIC (a, s);	\
	  a += b;	\
	}	\
      while (0)
		/* Round 2.  */
#  if MD5SUM_SIZE_VS_SPEED == 1
		pp = P_array;
		for (i = 0; i < 4; i++) {
			OP(FG, A, B, C, D, (int) (*pp++), 5, *pc++);
			OP(FG, D, A, B, C, (int) (*pp++), 9, *pc++);
			OP(FG, C, D, A, B, (int) (*pp++), 14, *pc++);
			OP(FG, B, C, D, A, (int) (*pp++), 20, *pc++);
		}
#  else
		OP(FG, A, B, C, D, 1, 5, 0xf61e2562);
		OP(FG, D, A, B, C, 6, 9, 0xc040b340);
		OP(FG, C, D, A, B, 11, 14, 0x265e5a51);
		OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
		OP(FG, A, B, C, D, 5, 5, 0xd62f105d);
		OP(FG, D, A, B, C, 10, 9, 0x02441453);
		OP(FG, C, D, A, B, 15, 14, 0xd8a1e681);
		OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
		OP(FG, A, B, C, D, 9, 5, 0x21e1cde6);
		OP(FG, D, A, B, C, 14, 9, 0xc33707d6);
		OP(FG, C, D, A, B, 3, 14, 0xf4d50d87);
		OP(FG, B, C, D, A, 8, 20, 0x455a14ed);
		OP(FG, A, B, C, D, 13, 5, 0xa9e3e905);
		OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8);
		OP(FG, C, D, A, B, 7, 14, 0x676f02d9);
		OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
#  endif	/* MD5SUM_SIZE_VS_SPEED == 1 */
		/* Round 3.  */
#  if MD5SUM_SIZE_VS_SPEED == 1
		for (i = 0; i < 4; i++) {
			OP(FH, A, B, C, D, (int) (*pp++), 4, *pc++);
			OP(FH, D, A, B, C, (int) (*pp++), 11, *pc++);
			OP(FH, C, D, A, B, (int) (*pp++), 16, *pc++);
			OP(FH, B, C, D, A, (int) (*pp++), 23, *pc++);
		}
#  else
		OP(FH, A, B, C, D, 5, 4, 0xfffa3942);
		OP(FH, D, A, B, C, 8, 11, 0x8771f681);
		OP(FH, C, D, A, B, 11, 16, 0x6d9d6122);
		OP(FH, B, C, D, A, 14, 23, 0xfde5380c);
		OP(FH, A, B, C, D, 1, 4, 0xa4beea44);
		OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9);
		OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60);
		OP(FH, B, C, D, A, 10, 23, 0xbebfbc70);
		OP(FH, A, B, C, D, 13, 4, 0x289b7ec6);
		OP(FH, D, A, B, C, 0, 11, 0xeaa127fa);
		OP(FH, C, D, A, B, 3, 16, 0xd4ef3085);
		OP(FH, B, C, D, A, 6, 23, 0x04881d05);
		OP(FH, A, B, C, D, 9, 4, 0xd9d4d039);
		OP(FH, D, A, B, C, 12, 11, 0xe6db99e5);
		OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8);
		OP(FH, B, C, D, A, 2, 23, 0xc4ac5665);
#  endif	/* MD5SUM_SIZE_VS_SPEED == 1 */
		/* Round 4.  */
#  if MD5SUM_SIZE_VS_SPEED == 1
		for (i = 0; i < 4; i++) {
			OP(FI, A, B, C, D, (int) (*pp++), 6, *pc++);
			OP(FI, D, A, B, C, (int) (*pp++), 10, *pc++);
			OP(FI, C, D, A, B, (int) (*pp++), 15, *pc++);
			OP(FI, B, C, D, A, (int) (*pp++), 21, *pc++);
		}
#  else
		OP(FI, A, B, C, D, 0, 6, 0xf4292244);
		OP(FI, D, A, B, C, 7, 10, 0x432aff97);
		OP(FI, C, D, A, B, 14, 15, 0xab9423a7);
		OP(FI, B, C, D, A, 5, 21, 0xfc93a039);
		OP(FI, A, B, C, D, 12, 6, 0x655b59c3);
		OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92);
		OP(FI, C, D, A, B, 10, 15, 0xffeff47d);
		OP(FI, B, C, D, A, 1, 21, 0x85845dd1);
		OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f);
		OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
		OP(FI, C, D, A, B, 6, 15, 0xa3014314);
		OP(FI, B, C, D, A, 13, 21, 0x4e0811a1);
		OP(FI, A, B, C, D, 4, 6, 0xf7537e82);
		OP(FI, D, A, B, C, 11, 10, 0xbd3af235);
		OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
		OP(FI, B, C, D, A, 9, 21, 0xeb86d391);
#  endif	/* MD5SUM_SIZE_VS_SPEED == 1 */
# endif	/* MD5SUM_SIZE_VS_SPEED > 1 */
		/* Add the starting values of the context.  */
		A += A_save;
		B += B_save;
		C += C_save;
		D += D_save;
	}
	/* Put checksum in context given as argument.  */
	ctx->A = A;
	ctx->B = B;
	ctx->C = C;
	ctx->D = D;
}
/* Starting with the result of former calls of this function (or the
 * initialization function update the context for the next LEN bytes
 * starting at BUFFER.
 * It is NOT required that LEN is a multiple of 64.
 */
static void md5_hash_bytes(const void *buffer, size_t len, struct md5_ctx_t *ctx)
{
	/* When we already have some bits in our internal buffer concatenate
	   both inputs first.  */
	if (ctx->buflen != 0) {
		size_t left_over = ctx->buflen;
		size_t add = 128 - left_over > len ? len : 128 - left_over;
		memcpy(&ctx->buffer[left_over], buffer, add);
		ctx->buflen += add;
		if (left_over + add > 64) {
			md5_hash_block(ctx->buffer, (left_over + add) & ~63, ctx);
			/* The regions in the following copy operation cannot overlap.  */
			memcpy(ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
				   (left_over + add) & 63);
			ctx->buflen = (left_over + add) & 63;
		}
		buffer = (const char *) buffer + add;
		len -= add;
	}
	/* Process available complete blocks.  */
	if (len > 64) {
		md5_hash_block(buffer, len & ~63, ctx);
		buffer = (const char *) buffer + (len & ~63);
		len &= 63;
	}
	/* Move remaining bytes in internal buffer.  */
	if (len > 0) {
		memcpy(ctx->buffer, buffer, len);
		ctx->buflen = len;
	}
}
static void md5_hash(const void *buffer, size_t length, void *md5_ctx)
{
	if (length % 64 == 0) {
		md5_hash_block(buffer, length, md5_ctx);
	} else {
		md5_hash_bytes(buffer, length, md5_ctx);
	}
}
/* Process the remaining bytes in the buffer and put result from CTX
 * in first 16 bytes following RESBUF.  The result is always in little
 * endian byte order, so that a byte-wise output yields to the wanted
 * ASCII representation of the message digest.
 *
 * IMPORTANT: On some systems it is required that RESBUF is correctly
 * aligned for a 32 bits value.
 */
static void *md5_end(void *resbuf, struct md5_ctx_t *ctx)
{
	/* Take yet unprocessed bytes into account.  */
	uint32_t bytes = ctx->buflen;
	size_t pad;
	/* Now count remaining bytes.  */
	ctx->total[0] += bytes;
	if (ctx->total[0] < bytes)
		++ctx->total[1];
	pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
# if MD5SUM_SIZE_VS_SPEED > 0
	memset(&ctx->buffer[bytes], 0, pad);
	ctx->buffer[bytes] = 0x80;
# else
	memcpy(&ctx->buffer[bytes], fillbuf, pad);
# endif	/* MD5SUM_SIZE_VS_SPEED > 0 */
	/* Put the 64-bit file length in *bits* at the end of the buffer.  */
	*(uint32_t *) & ctx->buffer[bytes + pad] = SWAP(ctx->total[0] << 3);
	*(uint32_t *) & ctx->buffer[bytes + pad + 4] =
		SWAP(((ctx->total[1] << 3) | (ctx->total[0] >> 29)));
	/* Process last bytes.  */
	md5_hash_block(ctx->buffer, bytes + pad + 8, ctx);
	/* Put result from CTX in first 16 bytes following RESBUF.  The result is
	 * always in little endian byte order, so that a byte-wise output yields
	 * to the wanted ASCII representation of the message digest.
	 *
	 * IMPORTANT: On some systems it is required that RESBUF is correctly
	 * aligned for a 32 bits value.
	 */
	((uint32_t *) resbuf)[0] = SWAP(ctx->A);
	((uint32_t *) resbuf)[1] = SWAP(ctx->B);
	((uint32_t *) resbuf)[2] = SWAP(ctx->C);
	((uint32_t *) resbuf)[3] = SWAP(ctx->D);
	return resbuf;
}
#endif	/* CONFIG_MD5SUM */
extern int hash_fd(int src_fd, const size_t size, const uint8_t hash_algo,
				   uint8_t * hashval)
{
	int result = EXIT_SUCCESS;
//	size_t hashed_count = 0;
	size_t blocksize = 0;
	size_t remaining = size;
	unsigned char *buffer = NULL;
	void (*hash_fn_ptr)(const void *, size_t, void *) = NULL;
	void *cx = NULL;
#ifdef CONFIG_SHA1SUM
	struct sha1_ctx_t sha1_cx;
#endif
#ifdef CONFIG_MD5SUM
	struct md5_ctx_t md5_cx;
#endif
#ifdef CONFIG_SHA1SUM
	if (hash_algo == HASH_SHA1) {
		/* Ensure that BLOCKSIZE is a multiple of 64.  */
		blocksize = 65536;
		buffer = xmalloc(blocksize);
		hash_fn_ptr = sha1_hash;
		cx = &sha1_cx;
	}
#endif
#ifdef CONFIG_MD5SUM
	if (hash_algo == HASH_MD5) {
		blocksize = 4096;
		buffer = xmalloc(blocksize + 72);
		hash_fn_ptr = md5_hash;
		cx = &md5_cx;
	}
#endif
	/* Initialize the computation context.  */
#ifdef CONFIG_SHA1SUM
	if (hash_algo == HASH_SHA1) {
		sha1_begin(&sha1_cx);
	}
#endif
#ifdef CONFIG_MD5SUM
	if (hash_algo == HASH_MD5) {
		md5_begin(&md5_cx);
	}
#endif
	/* Iterate over full file contents.  */
	while ((remaining == (size_t) -1) || (remaining > 0)) {
		size_t read_try;
		ssize_t read_got;
		if (remaining > blocksize) {
			read_try = blocksize;
		} else {
			read_try = remaining;
		}
		read_got = bb_full_read(src_fd, buffer, read_try);
		if (read_got < 1) {
			/* count == 0 means short read
			 * count == -1 means read error */
			result = read_got - 1;
			break;
		}
		if (remaining != (size_t) -1) {
			remaining -= read_got;
		}
		/* Process buffer */
		hash_fn_ptr(buffer, read_got, cx);
	}
	/* Finalize and write the hash into our buffer.  */
#ifdef CONFIG_SHA1SUM
	if (hash_algo == HASH_SHA1) {
		sha1_end(hashval, &sha1_cx);
	}
#endif
#ifdef CONFIG_MD5SUM
	if (hash_algo == HASH_MD5) {
		md5_end(hashval, &md5_cx);
	}
#endif
	free(buffer);
	return result;
}

 Ok, ma se volessi usare md5 o crc32 che header dovrei includere ?
MD5 puoi includere openSSL o molte altre alternative, CRC32 si include
il sorgente public-domain che si trova un po' ovunque, esempio una
appendice a questa RFC:
http://rfc.net/rfc1952.html
o anche 
http://en.wikipedia.org/wiki/Cyclic_redundancy_check
Tuttavia se l' ID e' un int costituito di una words di 32 bits, stringhe
di piu' di 32 bits SICURAMENTE avranno valori diversi che collideranno
allo stesso ID.
Puoi solo scegliere una funzione che distribuisca al meglio i valori
di ID, ma il funzionamento e' solo probabilistico.
E' un problema noto: l' accesso alle tabelle di hash e' tutto uno studiare
la gestione delle collisioni.


 la gestione delle collisioni.
dupalle!


Hai qualche vincolo sulle stringhe?
Per esempio, conosci la lunghezza massima delle stringhe che dovrai 
trattare?
I simboli usati nelle stringhe sono tutti i 256 elementi ascii o sono, 
per esempio, solo le lettere minuscole?
Queste risposte ti daranno un'idea della cardinalita' dell'insieme da 
codificare.
L'ID quanto deve essere grande?
Hai limiti sulla lunghezza dell'ID?
Quante strighe dovrai trattare?
Se non sono molte, diciamo un migliaio, puoi pensare di farti un piccolo 
  database di stringhe, assegnando un numero incrementale alle stringhe 
che vengono elaborate.
Ciao.
          Stefano

 
Per stringhe così poco lunghe, forse può capitare che l'id non sia 
univoco...tanto più è lunga, tanto più sarà difficile che venga generato
un id uguale

 
http://burtleburtle.net/bob/hash/doobs.html
Tra quelle indicate qual'e' quella che lui preferisce ?
Ho riletto varie volte, ma questa cosa non l'ho capita :(
Grazie inifinite


forse e' unaforzatura, ma non e' che per caso di va bene ftok?
man 3 ftok
per saperne di piu'