2011-04-04 29 views
12

Aquí está mi problema. Actualmente estoy intentando implementar algunos estándares de criptografía en PHP por razones de compatibilidad. El que estoy trabajando ahora es SHA256 y SHA512. Ambos son estándares razonablemente sencillos, y no estoy teniendo problemas con eso.Operaciones bit a bit en cadenas grandes en PHP

Sin embargo, SHA512 requiere operaciones bit a bit en enteros de 64 bits. Como PHP puede tener solo enteros de 32 bits (con la compilación), eso me deja con un problema. ¿Cómo implemento las funciones de bit a bit necesarias (módulo, cambio, rotar, agregar, xor y, o, etc.) para que ambos mantengan la compatibilidad y un nivel de rendimiento razonable ...

Conozco algunos de ellos la implementación de las funciones se hace trivialmente con 2 entradas de 32 bits. Sin embargo, ¿cómo funciona eso para shift y rotate?

Lo que he pensado hacer es almacenar las cadenas en forma binaria (como una cadena de 01010). De esta forma, todas las operaciones bit a bit serán completamente independientes de la arquitectura. Pero es probable que esto ocasione una caída masiva del rendimiento, ya que se usan con mucha frecuencia en los estándares (y en otras partes de la biblioteca).

Así que mi pregunta es: ¿cómo puedo permitir fácilmente operaciones de cadena de al menos 64 bits en una compilación de 32 bits de PHP sin dejar de mantener un nivel razonable de rendimiento para cada paso ...?

Ah, y mi objetivo es la portabilidad aquí, por lo que no hay extensiones. Otras bibliotecas las consideraré, pero deben ser portátiles ...

+2

Puede tratar un número de 64 bits como dos números de 32 bits y hacer malabares con la parte "acarrear" entre los dos números. –

+0

@Sal: seguro. Pero eso es una especie de PITA. Supongo que si es lo mejor que puedo hacer, que así sea. Pero si hay una manera más limpia, soy todo oídos ... – ircmaxell

+0

Generalice la funcionalidad creando un objeto "BitString" que sea solo un contenedor para la matriz de Ints con algunas funciones bit a bit que hacen lo que Salman menciona. –

Respuesta

2

Almacenar los valores en cadenas es realmente el camino correcto a seguir.

Pero en lugar de almacenar 1 y 0, solo almacene 8 bits en cada byte. Todavía será fácil extraer partes del entero de tu cadena. Necesitas hacer manualmente todas las operaciones, como el cambio.

+0

Bueno, la única razón por la que pensé en almacenar 0 y 1 en una cadena es que es trivial implementar cada operador en modo bit entonces (cambio a la izquierda simplemente agrega un 0, a la derecha es simplemente eliminar un dígito posterior, etc.). .. – ircmaxell

+0

Pero no será muy rápido. Si lo haces de forma binaria y extraes partes por byte (o por cada bit de 32) puedes seguir usando los operadores bit a bit estándar, pero debes asegurarte de todo como un cambio a la izquierda lleva a los siguientes dos bytes. – Evert

+0

Lo suficientemente justo @Evert. Tendré que pensar en esto por un tiempo. Muchas gracias ... – ircmaxell

0

Puede usar bcmath. Ha demostrado ser muy bueno y va con PHP desde 4.0.4

+0

De nuevo, las extensiones están fuera de la mesa. Sin mencionar que BCMath no tiene funciones bit a bit, así que no sirve de nada incluso si quisiéramos mencionarlas ... De nuevo, estoy buscando operaciones bit a bit, no solo matemática arbitraria ... – ircmaxell

0

Claramente, no hay forma de utilizar la estructura de datos nativa que representa las condiciones dadas a su entorno, por lo que debe usar una estructura de datos en la parte superior. Esto significará por supuesto que no podrá aplicar su ejemplo dado ... 0xFFFFFFFF >> 4 pero podría usar mystruct (0xFFFFFFFF) >> 4 (mystruct es la estructura de datos definida por usted).

Si esto suena como un plan, avíseme y tal vez pueda ayudarlo con el resto de la solución.

+0

considerando que PHP no permite a los operadores prioritarios (ni estructuras verdaderas), no estoy seguro si eso funcionará. Si conoces una forma en PHP para hacerlo, soy todo oídos ... – ircmaxell

+0

cuando hablo de estructuras de datos Estaba pensando en una instancia de clase, sin embargo, a diferencia de ocaml et al, tienes razón: no es posible anular operadores.:-( –

Cuestiones relacionadas