¿Cómo convertirías una cadena arbitraria en un entero único, que sería el mismo en todas las sesiones y plataformas de Python? Por ejemplo, hash('my string')
no funcionaría porque se devuelve un valor diferente para cada sesión y plataforma de Python.Hashing persistente de cadenas en Python
Respuesta
Si una función de hash realmente no funciona para usted, puede convertir la cadena en un número.
my_string = 'my string'
def string_to_int(s):
ord3 = lambda x : '%.3d' % ord(x)
return int(''.join(map(ord3, s)))
In[10]: string_to_int(my_string)
Out[11]: 109121032115116114105110103L
Esto es invertible, mediante la asignación de cada triplete a través de chr
.
def int_to_string(n)
s = str(n)
return ''.join([chr(int(s[i:i+3])) for i in range(0, len(s), 3)])
In[12]: int_to_string(109121032115116114105110103L)
Out[13]: 'my string'
utilizar un algoritmo de hash como MD5 o SHA1, a continuación, convertir el hexdigest
través int()
:
>>> import hashlib
>>> int(hashlib.md5('Hello, world!').hexdigest(), 16)
144653930895353261282233826065192032313L
Esta es una buena respuesta, pero técnicamente el entero producido no es única * *. Hay menos valores hash MD5 que cadenas disponibles. Sin embargo, las posibilidades de una colisión son muy bajas –
Este es el caso de cualquier método hash. – MatthieuW
¿Qué significa "muy bajo"? ¿No sería prudente utilizar este algoritmo en producción cuando se requiere exclusividad? – kalu
En primer lugar, es probable que no realmente quieren que los números enteros para ser realmente único. Si lo haces, tus números podrían ser de un tamaño ilimitado. Si eso es lo que realmente quiere, podría usar una biblioteca bignum e interpretar los bits de la cadena como la representación de un entero (potencialmente muy grande). Si sus cadenas pueden incluir el carácter \ 0, debe anteponer un 1, para que pueda distinguir, p. "\ 0 \ 0" desde "\ 0".
Ahora, si prefiere números de tamaño limitado, usará alguna forma de hash. MD5 funcionará, pero es excesivo para el propósito declarado. Recomiendo usar sdbm en su lugar, funciona muy bien. En C se ve así:
static unsigned long sdbm(unsigned char *str)
{
unsigned long hash = 0;
int c;
while (c = *str++)
hash = c + (hash << 6) + (hash << 16) - hash;
return hash;
}
La fuente, http://www.cse.yorku.ca/~oz/hash.html, también presenta algunas otras funciones hash.
Estás en lo cierto. Esto definitivamente sería un problema si estuviera tratando de convertir documentos enteros a un número. Sin embargo, para mi aplicación, solo convertiré cadenas cortas, generalmente menos de unas pocas docenas de caracteres. – Cerin
Éstos son mi implementación de algoritmos python27 enumerados aquí: http://www.cse.yorku.ca/~oz/hash.html. No tengo idea de si son eficientes o no.
from ctypes import c_ulong
def ulong(i): return c_ulong(i).value # numpy would be better if available
def djb2(L):
"""
h = 5381
for c in L:
h = ((h << 5) + h) + ord(c) # h * 33 + c
return h
"""
return reduce(lambda h,c: ord(c) + ((h << 5) + h), L, 5381)
def djb2_l(L):
return reduce(lambda h,c: ulong(ord(c) + ((h << 5) + h)), L, 5381)
def sdbm(L):
"""
h = 0
for c in L:
h = ord(c) + (h << 6) + (h << 16) - h
return h
"""
return reduce(lambda h,c: ord(c) + (h << 6) + (h << 16) - h, L, 0)
def sdbm_l(L):
return reduce(lambda h,c: ulong(ord(c) + (h << 6) + (h << 16) - h), L, 0)
def loselose(L):
"""
h = 0
for c in L:
h += ord(c);
return h
"""
return sum(ord(c) for c in L)
def loselose_l(L):
return reduce(lambda h,c: ulong(ord(c) + h), L, 0)
Aquí hay otra opción, bastante cruda (probablemente tiene muchas colisiones) y no muy legible.
Se trabajó con el propósito de generar un int (y más tarde, un color al azar) para diferentes cadenas:
aString = "don't panic"
reduce(lambda x,y:x+y, map(lambda x:ord(x[0])*x[1],zip(aString, range(1, len(aString)))))
- 1. Hashing persistente de Python Frozen Sets
- 2. Memorización persistente en Python
- 3. Subproceso de python persistente
- 4. ¿Qué es hashing de características (hashing-trick)?
- 5. Similitud hashing
- 6. Hashing universal
- 7. Python: cookie persistente, genera el campo `expires`
- 8. Cadenas mutables en Python
- 9. división de cadenas en Python
- 10. formato de cadenas en Python
- 11. formato de cadenas en Python
- 12. Python - Intersección de cadenas
- 13. expresiones de cadenas (Python)
- 14. cadenas Python Referencias de
- 15. Hashing de valores de puntero
- 16. hashing de cadena en tiempo de compilación
- 17. Historial de la línea de comandos de Python persistente
- 18. MySQL Hashing Function Implementation
- 19. Algoritmo hashing de cadenas rápidas con bajas tasas de colisión con entero de 32 bits
- 20. Hashing and Salaring values
- 21. casting cadenas en bruto python
- 22. Son cadenas agrupadas en Python
- 23. JSON-> cadenas en Python
- 24. Hashing Algorithm, its uses?
- 25. Hashing vs binarios de firma
- 26. Persistente vs no persistente - ¿Qué debería usar?
- 27. HttpURLConnection persistente en Java
- 28. Optimización de cobertura de cadenas en Python
- 29. Ejemplos de búsqueda de cadenas en Python
- 30. Métricas de similitud de cadenas en Python
Esto asigna '\ 0' y '\ 0 \ 0' a la misma cosa - debe anteponer un '1'. También esto es un poco ineficiente, podría usar la representación hexadecimal para que tenga números más pequeños (esto es equivalente a usar la representación binaria de la cadena e interpretarla como un número). – redtuna