2011-09-22 10 views
10

Hace poco estuve buscando un archivo de configuración que guardaba algunos valores crípticos. Por casualidad, tenía la fuente disponible, así que eché un vistazo a lo que estaba haciendo, y estaba guardando un montón de valores diferentes y cambiando los unos a los otros. Me desconcertó por qué alguien haría eso. Mi pregunta, entonces, es: ¿hay una ventaja obvia para almacenar datos numéricos de esta manera? Puedo ver cómo podría almacenar un valor un poco más pequeño, en bytes, pero parece mucho trabajo ahorrar un par de bytes de almacenamiento. También parece que sería significativamente más lento.¿Por qué cambiar de bit?

La otra posibilidad que se me ocurrió es que se utilizó con fines de ofuscación. ¿Es este un uso común de cambio de bit?

+2

ofuscación por desplazamiento de bits podría ser uno de los medios menos efectivos – KevinDTimm

+0

@KevinDTimm Una vez vi un archivo de configuración que se generó poniendo cada otro carácter en un búfer separado, y luego combinando los dos. Entonces el archivo 'configParam = true' se convirtió en' cnfgaa reofiPrm = tr'. Ahora, por un solo parámetro, podría parecer lo suficientemente ofuscado como para no darse cuenta de inmediato. Para que un archivo completo sea de esa manera, el patrón era bastante obvio. Lo único, no era solo un archivo de configuración, era un archivo de licencia ... Mmmhmm ... Supongo que simplemente tenerlo como texto sin formato e imponer una firma hash era demasiado complejo para ellos ... – corsiKa

Respuesta

5

desplazamiento de bits parece ser más común en las lenguas sistemas de nivel como C, C++ y montaje, pero lo he visto aquí y allá en C# también. No se usa a menudo tanto para ahorrar espacio, sin embargo, como lo es para uno (o ambos) de los dos motivos típicos:

  • Estás hablando con un sistema existente (o utilizando un protocolo establecido, o la generación de una archivo en un formato conocido) que requiere que las cosas se distribuyan con mucha precisión; y/o
  • La combinación de bits comprende un valor que a su vez es útil para la prueba.

Cualquier persona que lo utiliza en un lenguaje de alto nivel exclusivamente para ahorrar espacio o ofuscar su código es casi siempre antes de tiempo optimizando (y/o es un idiota). El ahorro de espacio raramente justifica la complejidad añadida, y los cambios de bit realmente no son lo suficientemente complejos para detener a alguien determinado a comprender su código.

+0

Me parece que esta es la respuesta: no parecía haber una justificación para la complejidad añadida en el archivo de configuración. Sin embargo, fue bueno saber acerca de los usos prácticos del cambio de bit. –

+0

Puede que necesite almacenar, por ejemplo, dos 'short's en un campo' int'eger en estado de sesión en ASP.net sin la sobrecarga de leer y bloquear la sesión para leer dos valores separados. También se guarda la sobrecarga de almacenar dos valores en la sesión. –

+2

@David: Y ese ... es un buen ejemplo de dónde * no debería * usarse. Al menos hasta que hayas perfilado y descubras que tu aplicación es demasiado lenta porque estás leyendo dos parámetros de sesión en lugar de uno. (PROTIP: a menos que sea Microsoft, es muy probable que *** no sea el caso. Lejos, * mucho * más probable es que su algoritmo apesta). – cHao

11

Este es uno de los usos comunes de cambio de bit. Hay varios beneficios:

1) Las operaciones de cambio de bit son rápidas.

2) Puede almacenar múltiples banderas en un solo valor.

Si usted tiene una aplicación que tiene varias características, pero sólo desea que ciertos (configurable) los habilitados, usted podría hacer algo como:

[Flags] 
public enum Features 
{ 
    Profile = 1, 
    Messaging = 1 << 1, 
    Signing = 1 << 2, 
    Advanced = 1 << 3 
} 

Y su único valor para habilitar la mensajería y avanzada serían:

(1 << 1) + (1 << 3) = 2 + 16 = 18 

<add name="EnabledFeatures" value="18" /> 

Y después de averiguar si una determinada característica está habilitada, que acaba de realizar algunas operaciones matemáticas sencillas bit a bit:

var AdvancedEnabled = 
    EnabledFeatures & Features.Advanced == Features.Advanced; 
+1

No puedo Sin embargo, imagina que es considerablemente más rápido cuando se recopilan un puñado de valores de un archivo ... y los ahorros de espacio en este tipo de aplicaciones parecen insignificantes. Tal vez el desarrollador simplemente fue con algo con lo que estaba familiarizado. –

+0

También puede hacer una lógica extraña y/o/Xor en el valor (que generalmente es una variable de estado) para descubrir estados de "fusión". Realmente extraño, pero lo vi en aplicaciones 3D, en la representación de Kernel, que en realidad es la única solución para mantener la complejidad de la lógica y no pagar en rendimiento. – Tigran

+1

¿En qué se diferencia esto de tener una enumeración con valores de 1,2,4,8,16 etc.? ¿Qué gana esto? –

4

Tengo un proyecto que almacena la matriz día/hora de horas disponibles durante una semana. Por lo tanto, tiene valores de 24x7 que deben almacenarse de alguna manera.

Elegí almacenarlo como 7 pulgadas, por lo que cada día se representa con un número entero, y cada hora en él como un bit. Solo un ejemplo donde puede ser útil.

enter image description here

+0

Beneficio adicional: 'if (available_hours [0]! = 0)' indica si está disponible el domingo (o el lunes, si le interesa). – cHao

+0

Sí, exactamente ... También con operaciones AND u OR simples, se pueden calcular varias superposiciones en un instante. –

+0

Útil e informativo. Puedo ver muchos lugares en los que podría usar esto. Sin embargo, la forma en que se usó (en un archivo de configuración) no parece justificada. –

1

A veces (especialmente en la programación anterior de Windows), habrá información codificada en bits de "alto orden" y "bajo orden" de un valor ... y a veces es necesario pasar para obtener la información.No estoy 100% seguro de las razones detrás de eso, aparte de que podría hacer que sea conveniente devolver un valor de 64 bits con dos valores de 32 bits codificados en él (para que pueda manejarlo con un único valor de retorno de un método) llamada).

Estoy de acuerdo con sus afirmaciones sobre la complejidad innecesaria, sin embargo, no veo muchas aplicaciones fuera de las cosas realmente crujientes de números/criptografía en las que esto sería necesario.

Cuestiones relacionadas