我想将多个块的值存储到整数中,就像我将ip转换为int一样。我的问题是我需要为n个块做这个,而不仅仅是4.我还需要指定每个块的最大值,对于所有块来说总是相同的。
因此,对于下面的示例,如果我想存储整个IP范围,我的BlockCount为4,而我的BlockSize为255,这是每个块的最大值。但是如果我降低我的BlockSize和/或BlockCount似乎无法工作。
这是我的第一次尝试,但它无法正常工作:
const int BlockSize = 100;
const int BlockCount = 3;
int shiftedValues = Shift(BlockSize, BlockCount);
for (int shiftedValue = 1; shiftedValue <= shiftedValues; shiftedValue++)
{
for (int index = 0; index <= BlockCount; index++)
{
int blockValue = Unshift(index, shiftedValue);
}
}
private static int Shift(int blockSize, int blockCount)
{
int result = 0;
for (int i = 0; i < blockCount; i++)
{
result += ( blockSize << 8 * i );
}
return result;
}
private static int Unshift(int blockIndex, int shiftedValue)
{
return ( shiftedValue >> ( blockIndex * 8 ) ) & 0xFF;
}
答案 0 :(得分:1)
上面的代码是我的解决方案,它是非常简单的代码,但随时可以要求澄清它。
class Program
{
static void Main(string[] args)
{
int [] items = { 150 , 78 , 44 } ;
int x = Program.Pack ( items , 150 ) ;
int [] unpacked = Program.UnPack ( x , 150 , 3 ) ;
}
public static int Pack ( int[] blocks , int blockSize )
{
int size = (int)Math.Ceiling(Math.Log(blockSize, 2));
int len = size * blocks.Length;
if (len > 32)
throw new Exception("Int Limit Exceeded");
if ( blocks.Any ( x => x > blockSize ) )
throw new Exception ( "There are some blocks that exceede the maximum block size" );
List<bool> bools = new List<bool>();
bools = bools.InitBoolArray(32);
int i = 0 ;
foreach (int block in blocks)
{
BitArray temp = block.ToBinary().Take(size);
for ( int j = 0 ; j < size ; i++ , j++ )
bools[i] = temp.Get(j);
}
return (new BitArray ( bools.ToArray() ) ).ToNumeral() ;
}
public static int[] UnPack ( int entry , int blockSize , int blockCount )
{
BitArray number = entry.ToBinary();
int size = (int)Math.Ceiling(Math.Log(blockSize, 2));
if (size > 32)
throw new Exception("Int Limit Exceeded");
List<int> result = new List<int>();
for (int i = 0; i < blockCount; i++)
{
BitArray temp = number.Take(size);
number = number.Shift (size );
result.Add(temp.FitSize(32).ToNumeral());
}
return result.ToArray() ;
}
}
使用扩展方法
public static class BinaryConverter
{
public static BitArray ToBinary(this int numeral)
{
return new BitArray(new[] { numeral });
}
public static int ToNumeral(this BitArray binary)
{
if (binary == null)
throw new ArgumentNullException("binary");
if (binary.Length > 32)
throw new ArgumentException("must be at most 32 bits long");
var result = new int[1];
binary.CopyTo(result, 0);
return result[0];
}
public static BitArray Take (this BitArray current, int length )
{
if (current.Length < length)
throw new Exception("Invalid length parameter");
List<bool> taken = new List<bool>();
for (int i = 0; i < length; i++)
taken.Add(current.Get(i));
return new BitArray(taken.ToArray());
}
public static BitArray Shift (this BitArray current, int length )
{
if (current.Length < length)
throw new Exception("Invalid length parameter");
List<bool> shifted = new List<bool>();
for (int i = 0; i < current.Length - length; i++)
shifted.Add(current.Get(length + i));
return new BitArray(shifted.ToArray());
}
public static BitArray FitSize (this BitArray current, int size)
{
List<bool> bools = new List<bool>() ;
bools = bools.InitBoolArray(size);
for (int i = 0; i < current.Count; i++)
bools[i] = current.Get(i) ;
return new BitArray(bools.ToArray());
}
public static List<bool> InitBoolArray(this List<bool> current, int size)
{
List<bool> bools = new List<bool> ();
for (int i = 0; i < size; i++)
bools.Add(false);
return bools ;
}
}