• Domingo 17 de Noviembre de 2024, 17:40

Autor Tema:   Obtener bits y convertirlos a algun valor  (Leído 2584 veces)

U2_Caparzo

  • Miembro activo
  • **
  • Mensajes: 45
  • Nacionalidad: cl
  • Super duper divertido xDD
    • Ver Perfil
Obtener bits y convertirlos a algun valor
« en: Viernes 21 de Septiembre de 2012, 07:42 »
0
Pues la verdad dudo que esto sirva de mucho en algun momento, lo queria integrar a la criptografia de una aplicacion que hacemos con un amigo, pero resulto que no era lo suficientemente rapido como para usarlo(no es que sea lento, pero si lo era para nosotros porque necesitamos transferencia de datos rapida por Tcp, y el aumentar el tiempo en varios ms no era lo ideal), asi que agrugue los metodos para todos los tipos de variables y aqui esta xD
     |10011011|
basicamente lo que hice es lo siguiente
suponiendo que lo que esta dentro de las lineas '|' es un byte (con un tamaño de 8 bits),  para obtener cada bit lo que hago es.
aplico el operador ">" o "<" para correr los bits, uso ">>" con una cantidad igual a 7, si el numero es 0, continuo corriendo los bits hasta que sea distinto de 0, asi obtengo la cantidad de bits en uso por el numero para crear la matriz de bytes(conteniendo cada byte uno 1 o un 0).

luego empujo los bits hacia la izquierda con "<<" para eliminar los bits anteriores al que deseo obtener. y luego a la izquierda, para que me quede como valores posibles un 1 o un 0 (Esto es solo util despues de haber obtenido el primer bit)

luego empujo uso >> 7 para obtener el byte, y lo agrego a la matriz para finalmente tener el bit dentro de la matriz

asi por ejemplo tenemos el siguiente byte, y queremos obtener el bit en negrita
 
  |00110011|
  aplico << 6  y queda
   |11000000|
aplico >> 7 y queda
  |00000001|
y como un numero con esos bits es igual a 1, o si el bit fuera 0 seria 0, obtengo el bit, y asi lo agrego a la matriz

al finalizar me di cuenta de que los bits estaban entregados al reves, asi que use Array.Reverse para invertirlos.

tambien agrugue los metodos para revertir el proceso.

la clase:

Código: [Seleccionar]

/// <summary>
    /// Clase con metodos para obtener una matriz de bits de un valor numerico
    /// o el valor numerico de una matriz de bits
    /// </summary>
    public class Bits
    {
        public static byte[] GetBits(sbyte source)
        {
            return GetBits((byte)source);
        }

        public static byte[] GetBits(byte source)
        {
            byte[] CompleteBits;
            byte BitsAmount = 8;
            byte Copy = source;
            for (int i = 7; i >= 0; i--)
            {
                if (source >> i == 0)
                    BitsAmount--;
                else
                    break;
            }
            CompleteBits = new byte[BitsAmount];
            for (int i = 0; i < BitsAmount; i++)
            {
                Copy <<= (7 - i);
                Copy >>= 7;
                CompleteBits[i] = Copy;
                Copy = source;
            }
            Array.Reverse(CompleteBits);
            return CompleteBits;
        }

        public static byte[] GetBits(short source)
        {
            return GetBits((ushort)source);
        }

        public static byte[] GetBits(ushort source)
        {
            byte[] CompleteBits;
            byte BitsAmount = 16;
            ushort Copy = source;
            for (int i = 15; i >= 0; i--)
            {
                if (source >> i == 0)
                    BitsAmount--;
                else
                    break;
            }
            CompleteBits = new byte[BitsAmount];
            for (int i = 0; i < BitsAmount; i++)
            {
                Copy <<= (15 - i);
                Copy >>= 15;
                CompleteBits[i] = (byte)Copy;
                Copy = source;
            }
            Array.Reverse(CompleteBits);
            return CompleteBits;
        }

        public static byte[] GetBits(int source)
        {
            return GetBits((uint)source);
        }

        public static byte[] GetBits(uint source)
        {
            byte[] CompleteBits;
            byte BitsAmount = 32;
            uint Copy = source;
            for (int i = 31; i >= 0; i--)
            {
                if (source >> i == 0)
                    BitsAmount--;
                else
                    break;
            }
            CompleteBits = new byte[BitsAmount];
            for (int i = 0; i < BitsAmount; i++)
            {
                Copy <<= (31 - i);
                Copy >>= 31;
                CompleteBits[i] = (byte)Copy;
                Copy = source;
            }
            Array.Reverse(CompleteBits);
            return CompleteBits;
        }

        public static byte[] GetBits(long source)
        {
            return GetBits((ulong)source);
        }

        public static byte[] GetBits(ulong source)
        {
            byte[] CompleteBits;
            byte BitsAmount = 64;
            ulong Copy = source;
            for (int i = 63; i >= 0; i--)
            {
                if (source >> i == 0)
                    BitsAmount--;
                else
                    break;
            }
            CompleteBits = new byte[BitsAmount];
            for (int i = 0; i < BitsAmount; i++)
            {
                Copy <<= (63 - i);
                Copy >>= 63;
                CompleteBits[i] = (byte)Copy;
                Copy = source;
            }
            Array.Reverse(CompleteBits);
            return CompleteBits;
        }

        public static sbyte GetSByte(byte[] source)
        {
            return (sbyte)GetByte(source);
        }

        public static byte GetByte(byte[] source)
        {
            byte ToReturn = 0;
            for (int i = 0; i < source.Length; i++)
            {
                ToReturn += (byte)(source[i] << (source.Length - i - 1));
            }
            return ToReturn;
        }

        public static short GetInt16(byte[] source)
        {
            return (short)GetUInt32(source);
        }

        public static ushort GetUInt16(byte[] source)
        {
            ushort ToReturn = 0;
            for (int i = 0; i < source.Length; i++)
            {
                ToReturn += (ushort)(source[i] << (source.Length - i - 1));
            }
            return ToReturn;
        }

        public static int GetInt32(byte[] source)
        {
            return (int)GetUInt32(source);
        }

        public static uint GetUInt32(byte[] source)
        {
            uint ToReturn = 0;
            for (int i = 0; i < source.Length; i++)
            {
                ToReturn += (uint)(source[i] << (source.Length - i - 1));
            }
            return ToReturn;
        }

        public static long GetInt64(byte[] source)
        {
            return (long)GetUInt64(source);
        }

        public static ulong GetUInt64(byte[] source)
        {
            ulong ToReturn = 0;
            for (int i = 0; i < source.Length; i++)
            {
                ToReturn += (ulong)(source[i] << (source.Length - i - 1));
            }
            return ToReturn;
        }
    }

si no entienden que es, vayan a la calculadora de windows, la dejan en modo cientifico, escriben cualquier numero en "dec" y luego apretan en "bin", lo que obtienes, lo tendras como byte[] usando los metodos que puse.

No se si hayan mejores maneras de hacerlo dadas por .Net pero esto funciona relativamente rapido
Lo dificil se hace... lo imposible se intenta
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.(Frase de Albert Einstein)

Sined99

  • Miembro activo
  • **
  • Mensajes: 56
    • Ver Perfil
Re: Obtener bits y convertirlos a algun valor
« Respuesta #1 en: Viernes 21 de Septiembre de 2012, 10:24 »
0
Hola,
Yo transformo Ushort a bits y viceversa
Código: [Seleccionar]
private bool[] getBits(ushort word){
return (new BitArray(BitConverter.GetBytes(word))).Cast<bool>.ToArray();
}

con este sencillo metodo transformo un ushort en un array de bool[]. Puedes investigar un poco y seria muy facil transformar un byte en bool[].

Un saludo.

Sined99

  • Miembro activo
  • **
  • Mensajes: 56
    • Ver Perfil
Re: Obtener bits y convertirlos a algun valor
« Respuesta #2 en: Viernes 21 de Septiembre de 2012, 10:34 »
0
Hola de nuevo,

Se me olvido comentar antes, que para para transformar un bool[] a ushort tambien es muy sencillo
Código: [Seleccionar]
private ushort getUshort(bool[] bits){
string aux="";
for(int i=bits.lenght - 1;i>=0; i--){
aux+=bits[i] ? "1" : "0";
}
return Convert.ToUint16(aux,2);
}

Tambien en este caso si modificas algo el metodo podras obtener un byte en vez de un ushort.

Saludos.


U2_Caparzo

  • Miembro activo
  • **
  • Mensajes: 45
  • Nacionalidad: cl
  • Super duper divertido xDD
    • Ver Perfil
Re: Obtener bits y convertirlos a algun valor
« Respuesta #3 en: Viernes 21 de Septiembre de 2012, 20:32 »
0
Gracias :P, luego de haber hecho esto hice una leida rapida sobre BitArray pero no lo habia entendido del todo ^^.
Lo dificil se hace... lo imposible se intenta
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.(Frase de Albert Einstein)