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
|001100
11|
aplico << 6 y queda
|
11000000|
aplico >> 7 y queda
|0000000
1|
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:
/// <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