What is a fastest way to convert int to 4 bytes in C# ?
Fastest as in execution time not development time.
My own solution is this code:
byte[] bytes = new byte[4];
unchecked
{
bytes[0] = (byte)(data >> 24);
bytes[1] = (byte)(data >> 16);
bytes[2] = (byte)(data >> 8);
bytes[3] = (byte)(data);
}
Right now I see that my solution outperforms both struct and BitConverter by couple of ticks.
I think the unsafe is probably the fastest option and accept that as an answer but I would prefer to use a managed option.
A byte* cast using unsafe code is by far the fastest:
unsafe static void Main(string[] args) {
int i = 0x12345678;
byte* pi = (byte*)&i;
byte lsb = pi[0];
// etc..
}
That's what BitConverter does as well, this code avoids the cost of creating the array.
What is a fastest way to convert int to 4 bytes in C# ?
Using a BitConverter and it's GetBytes overload that takes a 32 bit integer:
int i = 123;
byte[] buffer = BitConverter.GetBytes(i);
The fastest way is with a struct containing 4 bytes.
In a defined layout (at byte position 0, 1, 2, 3
And an int32 that starts at position 0.
Put in the 4 variables, read out the byte.
Finished.
Significantly faster than the BitConverter.
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute.aspx
has the necessary attribute.
[StructLayout(LayoutKind.Explicit)]
struct FooUnion
{
[FieldOffset(0)]
public byte byte0;
[FieldOffset(1)]
public byte byte1;
[FieldOffset(2)]
public byte byte2;
[FieldOffset(3)]
public byte byte3;
[FieldOffset(0)]
public int integer;
}
I have done a research on the times needed to serialize a basic type to byte array. I did it for the case when you already have an array and offset where you want to put your data. I guess that's really an important case compared to theoretical get an array of 4 bytes because when you are serializing something then it's exactly what you need. I have figured out that the answer to what method is faster depends on what type you want to serialize. I have tried few methods:
Unsafe reference with an additional buffer overrun check
GetBytes + consequent Buffer.BulkCopy (This is essentially the same as 1 plus overhead)
Direct assignment with shift (
m_Bytes[offset] = (byte)(value >> 8)
Direct assignment with shift and bitwise &
m_Bytes[offset] = (byte)((i >> 8) & 0xFF)
I ran all of the test 10 mln times. Below are the results in milliseconds
Long Int Short Byte Float Double
1 29 32 31 30 29 34
2 209 233 220 212 208 228
3 63 24 13 8 24 44
4 72 29 14
As you can see the unsafe way is much faster for long and double (unsigned versions are about the same as their signed versions so they are not in the table). For short/int/float the fastest way is the 2/4/4 assignments with shift. For byte the fastest is obviously the simple assignment. So regarding the original question - the assignment way is the best. This is the example of such a function in a fastest way:
public static void WriteInt(byte[] buffer, int offset, int value)
{
m_BytesInt[offset] = (byte)(value >> 24);
m_BytesInt[offset + 1] = (byte)(value >> 16);
m_BytesInt[offset + 2] = (byte)(value >> 8);
m_BytesInt[offset + 3] = (byte) value;
}
P.S. The tests were run on x64 environment with code compiled to cpu any (which was x64 on run) in release mode.
Note the BitConverter may not be the fastest as the test below shows.
Use the BitConverter class, specifically the GetBytes method that takes an Int32 parameter:
var myInt = 123;
var bytes = BitConverter.GetBytes(myInt);
You can use BitConverter.IsLittlEndian to determine the byte order based on the CPU architecture.
EDIT: The test below isn't conclusive due to compiler optimisations.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
[StructLayout(LayoutKind.Explicit)]
struct FooUnion
{
[FieldOffset(0)]
public byte byte0;
[FieldOffset(1)]
public byte byte1;
[FieldOffset(2)]
public byte byte2;
[FieldOffset(3)]
public byte byte3;
[FieldOffset(0)]
public int integer;
}
class Program
{
static void Main(string[] args)
{
testUnion();
testBitConverter();
Stopwatch Timer = new Stopwatch();
Timer.Start();
testUnion();
Timer.Stop();
Console.WriteLine(Timer.ElapsedTicks);
Timer = new Stopwatch();
Timer.Start();
testBitConverter();
Timer.Stop();
Console.WriteLine(Timer.ElapsedTicks);
Console.ReadKey();
}
static void testBitConverter()
{
byte[] UnionBytes;
for (int i = 0; i < 10000; i++)
{
UnionBytes = BitConverter.GetBytes(i);
}
}
static void testUnion()
{
byte[] UnionBytes;
for (int i = 0; i < 10000; i++)
{
FooUnion union = new FooUnion() { integer = i };
UnionBytes = new byte[] { union.byte0, union.byte1, union.byte2, union.byte3 };
}
}
}
}
As many in here seem to argue about if BitConverter is beter than a dedicated struct. Based on BCL source code the BitConverter.GetBytes() looks like this:
public static unsafe byte[] GetBytes(int value)
{
byte[] buffer = new byte[4];
fixed (byte* bufferRef = buffer)
{
*((int*)bufferRef) = value;
}
return buffer;
}
Which from my point of view is more clean and seems faster than making 1 integer + 4 byte assignments to a explicit struct as this one.
[StructLayout(LayoutKind.Explicit)]
struct IntByte
{
[FieldOffset(0)]
public int IntVal;
[FieldOffset(0)]
public byte Byte0;
[FieldOffset(1)]
public byte Byte1;
[FieldOffset(2)]
public byte Byte2;
[FieldOffset(3)]
public byte Byte3;
}
new IntByte { IntVal = 10 } -> Byte0, Byte1, Byte2, Byte3.
class Program
{
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
unsafe{
byte[] byteArray = new byte[4];
for(int i = 0; i != int.MaxValue; ++i)
{
fixed(byte* asByte = byteArray)
*((int*)asByte) = 43;
}
}
Console.WriteLine(sw.ElapsedMilliseconds);
Console.Read();
}
}
Averages around 2770ms on my machine while
[StructLayout(LayoutKind.Explicit)]
struct Switcher
{
[FieldOffset(0)]
public int intVal;
[FieldOffset(0)]
public byte b0;
[FieldOffset(1)]
public byte b1;
[FieldOffset(2)]
public byte b2;
[FieldOffset(3)]
public byte b3;
}
class Program
{
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
byte[] byteArray = new byte[4];
Switcher swi = new Switcher();
for(int i = 0; i != int.MaxValue; ++i)
{
swi.intVal = 43;
byteArray[0] = swi.b0;
byteArray[1] = swi.b1;
byteArray[2] = swi.b2;
byteArray[3] = swi.b3;
}
Console.WriteLine(sw.ElapsedMilliseconds);
Console.Read();
}
}
Averages around 4510ms.
I think this might be the fastest way in C#.. (with byte array initialized to 4x the int stream w/ int32
private MemoryStream Convert(int[] Num, byte[] Bytes)
{
Buffer.BlockCopy(Num, 0, Bytes, 0, Bytes.Length);
MemoryStream stream = new MemoryStream(Bytes);
return stream;
}
Union is the fastest way of splitting an integer into bytes. Below is a complete program in which the C# optimizer can't optimize the byte splitting operation out, because each byte is summed and the sum is printed out.
The timings on my laptop are 419 milliseconds for the Union and 461 milliseconds for the BitConverter. The speed gain, however, is much greater.
This method is used in an open source high-performance algorithms HPCsharp library, where the Union method provides a nice performance boost for the Radix Sort.
Union is faster because it performs no bitwise masking and no bit-shift, but simply reads the proper byte out of the 4-byte integer.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace SplitIntIntoBytes
{
[StructLayout(LayoutKind.Explicit)]
struct FooUnion
{
[FieldOffset(0)]
public byte byte0;
[FieldOffset(1)]
public byte byte1;
[FieldOffset(2)]
public byte byte2;
[FieldOffset(3)]
public byte byte3;
[FieldOffset(0)]
public int integer;
}
class Program
{
static void Main(string[] args)
{
testUnion();
testBitConverter();
Stopwatch Timer = new Stopwatch();
Timer.Start();
int sumTestUnion = testUnion();
Timer.Stop();
Console.WriteLine("time of Union: " + Timer.ElapsedTicks + " milliseconds, sum: " + sumTestUnion);
Timer.Restart();
int sumBitConverter = testBitConverter();
Timer.Stop();
Console.WriteLine("time of BitConverter: " + Timer.ElapsedTicks + " milliseconds, sum: " + sumBitConverter);
Console.ReadKey();
}
static int testBitConverter()
{
byte[] UnionBytes = new byte[4];
byte[] SumOfBytes = new byte[4];
SumOfBytes[0] = SumOfBytes[1] = SumOfBytes[2] = SumOfBytes[3] = 0;
for (int i = 0; i < 10000; i++)
{
UnionBytes = BitConverter.GetBytes(i);
SumOfBytes[0] += UnionBytes[0];
SumOfBytes[1] += UnionBytes[1];
SumOfBytes[2] += UnionBytes[2];
SumOfBytes[3] += UnionBytes[3];
}
return SumOfBytes[0] + SumOfBytes[1] + SumOfBytes[2] + SumOfBytes[3];
}
static int testUnion()
{
byte[] UnionBytes;
byte[] SumOfBytes = new byte[4];
SumOfBytes[0] = SumOfBytes[1] = SumOfBytes[2] = SumOfBytes[3] = 0;
FooUnion union = new FooUnion();
for (int i = 0; i < 10000; i++)
{
union.integer = i;
UnionBytes = new byte[] { union.byte0, union.byte1, union.byte2, union.byte3 };
SumOfBytes[0] += UnionBytes[0];
SumOfBytes[1] += UnionBytes[1];
SumOfBytes[2] += UnionBytes[2];
SumOfBytes[3] += UnionBytes[3];
}
return SumOfBytes[0] + SumOfBytes[1] + SumOfBytes[2] + SumOfBytes[3];
}
}
}
Related
I am uploading frames from a camera to a texture on the GPU for processing (using SharpDX). My issue is ATM is that I have the frames coming in as 24bit RGB, but DX11 no longer has the 24bit RGB texture format, only 32bit RGBA. After each 3 bytes I need to add another byte with the value of 255 (no transparency). I've tried this method of iterating thru the byte array to add it but it's too expensive. Using GDI bitmaps to convert is also very expensive.
int count = 0;
for (int i = 0; i < frameDataBGRA.Length - 3; i+=4)
{
frameDataBGRA[i] = frameData[i - count];
frameDataBGRA[i + 1] = frameData[(i + 1) - count];
frameDataBGRA[i + 2] = frameData[(i + 2) - count];
frameDataBGRA[i + 3] = 255;
count++;
}
Assuming you can compile with unsafe, using pointers in that case will give you significant boost.
First create two structs to hold data in a packed way:
[StructLayout(LayoutKind.Sequential)]
public struct RGBA
{
public byte r;
public byte g;
public byte b;
public byte a;
}
[StructLayout(LayoutKind.Sequential)]
public struct RGB
{
public byte r;
public byte g;
public byte b;
}
First version :
static void Process_Pointer_PerChannel(int pixelCount, byte[] rgbData, byte[] rgbaData)
{
fixed (byte* rgbPtr = &rgbData[0])
{
fixed (byte* rgbaPtr = &rgbaData[0])
{
RGB* rgb = (RGB*)rgbPtr;
RGBA* rgba = (RGBA*)rgbaPtr;
for (int i = 0; i < pixelCount; i++)
{
rgba->r = rgb->r;
rgba->g = rgb->g;
rgba->b = rgb->b;
rgba->a = 255;
rgb++;
rgba++;
}
}
}
}
This avoids a lot of indexing, and passes data directly.
Another version which is slightly faster, to box directly:
static void Process_Pointer_Cast(int pixelCount, byte[] rgbData, byte[] rgbaData)
{
fixed (byte* rgbPtr = &rgbData[0])
{
fixed (byte* rgbaPtr = &rgbaData[0])
{
RGB* rgb = (RGB*)rgbPtr;
RGBA* rgba = (RGBA*)rgbaPtr;
for (int i = 0; i < pixelCount; i++)
{
RGB* cp = (RGB*)rgba;
*cp = *rgb;
rgba->a = 255;
rgb++;
rgba++;
}
}
}
}
One small extra optimization (which is marginal), if you keep the same array all the time and reuse it, you can initialize it once with alpha set to 255 eg :
static void InitRGBA_Alpha(int pixelCount, byte[] rgbaData)
{
for (int i = 0; i < pixelCount; i++)
{
rgbaData[i * 4 + 3] = 255;
}
}
Then as you will never change this channel, other functions do not need to write into it anymore:
static void Process_Pointer_Cast_NoAlpha (int pixelCount, byte[] rgbData, byte[] rgbaData)
{
fixed (byte* rgbPtr = &rgbData[0])
{
fixed (byte* rgbaPtr = &rgbaData[0])
{
RGB* rgb = (RGB*)rgbPtr;
RGBA* rgba = (RGBA*)rgbaPtr;
for (int i = 0; i < pixelCount; i++)
{
RGB* cp = (RGB*)rgba;
*cp = *rgb;
rgb++;
rgba++;
}
}
}
}
In my test (running a 1920*1080 image, 100 iterations), I get (i7, x64 release build, average running time)
Your version : 6.81ms
Process_Pointer_PerChannel : 4.3ms
Process_Pointer_Cast : 3.8ms
Process_Pointer_Cast_NoAlpha : 3.5ms
Please note that of course all those functions can as well be easily chunked and parts run in multi threaded versions.
If you need higher performance, you have two options ( a bit out of scope from the question)
upload your image in a byte address buffer (as rgb), and perform the conversion to texture in a compute shader. That involves some bit shifting and a bit of fiddling with formats, but is reasonably straightforward to achieve.
Generally camera images come in Yuv format (with u and v downsampled), so it's mush faster to upload image in that color space and perform conversion to rgba either in pixel shader or compute shader. If your camera sdk allows to get pixel data in that native format, that's the way to go.
#catflier: good work, but it can go a little faster. ;-)
Reproduced times on my hardware:
Base version: 5.48ms
Process_Pointer_PerChannel: 2.84ms
Process_Pointer_Cast: 2.16ms
Process_Pointer_Cast_NoAlpha: 1.60ms
My experiments:
FastConvert: 1.45ms
FastConvert4: 1.13ms (here: count of pixels must be divisible by 4, but is usually no problem)
Things that have improved speed:
your RGB structure must always read 3 single bytes per pixel, but it is faster to read a whole uint (4 bytes) and simply ignore the last byte
the alpha value can then be added directly to a uint bit calculation
modern processors can often address fixed pointers with offset positions faster than pointers that are incremented themselves.
the offset variables in x64 mode should also directly use a 64-bit data value (long instead of int), which reduces the overhead of the accesses
the partial rolling out of the inner loop increases some performance again
The Code:
static void FastConvert(int pixelCount, byte[] rgbData, byte[] rgbaData)
{
fixed (byte* rgbP = &rgbData[0], rgbaP = &rgbaData[0])
{
for (long i = 0, offsetRgb = 0; i < pixelCount; i++, offsetRgb += 3)
{
((uint*)rgbaP)[i] = *(uint*)(rgbP + offsetRgb) | 0xff000000;
}
}
}
static void FastConvert4Loop(long pixelCount, byte* rgbP, byte* rgbaP)
{
for (long i = 0, offsetRgb = 0; i < pixelCount; i += 4, offsetRgb += 12)
{
uint c1 = *(uint*)(rgbP + offsetRgb);
uint c2 = *(uint*)(rgbP + offsetRgb + 3);
uint c3 = *(uint*)(rgbP + offsetRgb + 6);
uint c4 = *(uint*)(rgbP + offsetRgb + 9);
((uint*)rgbaP)[i] = c1 | 0xff000000;
((uint*)rgbaP)[i + 1] = c2 | 0xff000000;
((uint*)rgbaP)[i + 2] = c3 | 0xff000000;
((uint*)rgbaP)[i + 3] = c4 | 0xff000000;
}
}
static void FastConvert4(int pixelCount, byte[] rgbData, byte[] rgbaData)
{
if ((pixelCount & 3) != 0) throw new ArgumentException();
fixed (byte* rgbP = &rgbData[0], rgbaP = &rgbaData[0])
{
FastConvert4Loop(pixelCount, rgbP, rgbaP);
}
}
I am passed a byte array which is then converted to arrays of primitives using System.Buffer.BlockCopy. Essentially my code looks like this:
void Convert(byte[] b)
{
int[] i1 = new int[100]; // real arrays much larger
double[] d1 = new double[100];
int iPos=0, iSize;
iSize = i1.Length * sizeof(int);
System.Buffer.BlockCopy(b, iPos, i1, 0, iSize);
iPos += iSize;
iSize = d1.Length * sizeof(double);
System.Buffer.BlockCopy(b, iPos, d1, 0, iSize);
iPos += iSize;
//etc: lots of arrays
b=null;
}
This is quite performant, but it's memory usage is obviously 2x the size of my byte array until b is freed.
Is there any way to directly cast sections of the byte array to my primitive arrays? One that does not involve copying the data (therefore doesn't double the memory usage), and presumably is even faster?
You can use unsafe code (I don't if you are allowed to use it). But you can try something like this (no need to use extra arrays, just the array of bytes):
unsafe public void Convert(void* b)
{
int i;
double* asDouble = (double*)b;
double sum1 = 0.0;
for (i = 0; i < 100; i++, asDouble++)
sum1 += *asDouble;
int* asInt = (int*)asDouble;
int sum2 = 0;
for (i = 0; i < 100; i++, asInt++)
sum2 += *asInt;
}
public unsafe void SomeThing()
{
byte[] rawbytes = new byte[44000];
// Fill the "rawbytes" array somehow
fixed (byte* ptr = rawbytes)
{
Convert(ptr);
}
}
It is possible using unsafe code. One solution using a union (what my not be applicable in your situation)
namespace TestApplication
{
using System;
using System.Runtime.InteropServices;
internal static class Program
{
private static unsafe void Main()
{
var x = new ByteDoubleUnion();
x.bytes[0] = 24;
x.bytes[1] = 45;
x.bytes[2] = 68;
x.bytes[3] = 84;
x.bytes[4] = 251;
x.bytes[5] = 33;
x.bytes[6] = 9;
x.bytes[7] = 64;
// Prints pi.
Console.WriteLine(x.doubleValue);
Console.ReadLine();
}
}
[StructLayout(LayoutKind.Explicit)]
internal unsafe struct ByteDoubleUnion
{
[FieldOffset(0)]
internal Double doubleValue;
[FieldOffset(0)]
internal fixed Byte bytes[8];
}
}
and one solution just casting pointers.
namespace TestApplication
{
using System;
internal static class Program
{
private static unsafe void Main()
{
var bytes = new Byte[] { 24, 45, 68, 84, 251, 33, 9, 64 };
fixed (Byte* p = &bytes[0])
{
// Prints pi, too.
Console.WriteLine(*((Double*)p));
}
Console.ReadLine();
}
}
}
This is an attempt with unioned structure of arrays (unlike the array of struct in other postings) because this should be faster.
[StructLayout(LayoutKind.Explicit)]
public unsafe struct ByteBuffer
{
public const int IntSize=10;
public const int DoubleSize=5;
public const int IntBytes=sizeof(int)*IntSize;
public const int DoubleBytes=sizeof(double)*DoubleSize;
// Int array is unioned with byte array
[FieldOffset(0)]
fixed int int_array[IntSize];
[FieldOffset(0)]
fixed byte int_array_bytes[IntBytes];
// Double array us unioned with byte array
[FieldOffset(IntBytes)]
fixed double double_array[DoubleSize];
[FieldOffset(IntBytes)]
fixed byte double_array_bytes[DoubleBytes];
// Take array of bytes and distribute it
// by byte to each array
public ByteBuffer(byte[] b)
{
fixed(byte* ptr=int_array_bytes)
{
for(int i=0; i<IntBytes; i++)
{
ptr[i]=b[i];
}
}
fixed(byte* ptr=double_array_bytes)
{
for(int i=0; i<DoubleBytes; i++)
{
ptr[i]=b[IntBytes+i];
}
}
}
// Convert unmanaged array to managed array
public int[] ToIntArray()
{
int[] result=new int[IntSize];
fixed(int* ptr=int_array)
{
for(int i=0; i<IntSize; i++)
{
result[i]=ptr[i];
}
}
return result;
}
// Convert unmanaged array to managed array
public double[] ToDoubleArray()
{
double[] result=new double[DoubleSize];
fixed(double* ptr=double_array)
{
for(int i=0; i<DoubleSize; i++)
{
result[i]=ptr[i];
}
}
return result;
}
}
class Program
{
static void Main(string[] args)
{
// Load up with test data
byte[] data=new byte[..];
// I tested with 10 ints and 5 doubles encoded into bytes
//Now to test the Fast conversion
ByteBuffer bb=new ByteBuffer(data);
int[] data1=bb.ToIntArray();
double[] data2=bb.ToDoubleArray();
}
}
I need to serialize a bunch of floats and convert to little endian if necessary. I'm aware of BitConverter.GetBytes(float), but I'd rather avoid allocating a ton of little 4-byte arrays on the GC heap. How can I do the conversion into an existing large byte[] array with an offset index? I want something like:
float[] theFloats; // filled up somewhere
byte[] theBytes = new byte[theFloats.Length * 4];
int offset = 0;
for (int i = 0; i < numFloats; ++i)
{
MagicClass.CopyFloatToBytes(theFloats[i], theBytes, offset);
offset += 4;
}
You can create a MemoryStream around the array, then create a BinaryWriter and write floats to it.
Why not just use BitConverter.GetBytes?
You can also do this with [StructLayout(LayoutKind.Explicit)]
[StructLayout(LayoutKind.Explicit)]
public struct Convert32BitType
{
[FieldOffset(0)]
public int Int32Value;
[FieldOffset(0)]
public float FloatValue;
}
// Example:
var tmp = new Convert32BitType();
tmp.FloatValue = 1.1;
int ival = tmp.Int32Value;
byte b1 = (byte)(ival >> 24);
byte b2 = (byte)(ival >> 16);
byte b3 = (byte)(ival >> 8);
byte b4 = (byte)(ival >> 0);
Another possibility is to used the fixed keyword and cast the pointer, but that requires unsafe code.
I am currently using BitConverter to package two unsigned shorts inside a signed int. This code executes millions of times for different values and I am thinking the code could be optimized further. Here is what I am currently doing -- you can assume the code is C#/NET.
// to two unsigned shorts from one signed int:
int xy = 343423;
byte[] bytes = BitConverter.GetBytes(xy);
ushort m_X = BitConverter.ToUInt16(bytes, 0);
ushort m_Y = BitConverter.ToUInt16(bytes, 2);
// convet two unsigned shorts to one signed int
byte[] xBytes = BitConverter.GetBytes(m_X);
byte[] yBytes = BitConverter.GetBytes(m_Y);
byte[] bytes = new byte[] {
xBytes[0],
xBytes[1],
yBytes[0],
yBytes[1],
};
return BitConverter.ToInt32(bytes, 0);
So it occurs to me that I can avoid the overhead of constructing arrays if I bitshift. But for the life of me I can't figure out what the correct shift operation is. My first pathetic attempt involved the following code:
int xy = 343423;
const int mask = 0x00000000;
byte b1, b2, b3, b4;
b1 = (byte)((xy >> 24));
b2 = (byte)((xy >> 16));
b3 = (byte)((xy >> 8) & mask);
b4 = (byte)(xy & mask);
ushort m_X = (ushort)((xy << b4) | (xy << b3));
ushort m_Y = (ushort)((xy << b2) | (xy << b1));
Could someone help me? I am thinking I need to mask the upper and lower bytes before shifting. Some of the examples I see include subtraction with type.MaxValue or an arbitrary number, like negative twelve, which is pretty confusing.
** Update **
Thank you for the great answers. Here are the results of a benchmark test:
// 34ms for bit shift with 10M operations
// 959ms for BitConverter with 10M operations
static void Main(string[] args)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
for (int i = 0; i < 10000000; i++)
{
ushort x = (ushort)i;
ushort y = (ushort)(i >> 16);
int result = (y << 16) | x;
}
stopWatch.Stop();
Console.WriteLine((int)stopWatch.Elapsed.TotalMilliseconds + "ms");
stopWatch.Start();
for (int i = 0; i < 10000000; i++)
{
byte[] bytes = BitConverter.GetBytes(i);
ushort x = BitConverter.ToUInt16(bytes, 0);
ushort y = BitConverter.ToUInt16(bytes, 2);
byte[] xBytes = BitConverter.GetBytes(x);
byte[] yBytes = BitConverter.GetBytes(y);
bytes = new byte[] {
xBytes[0],
xBytes[1],
yBytes[0],
yBytes[1],
};
int result = BitConverter.ToInt32(bytes, 0);
}
stopWatch.Stop();
Console.WriteLine((int)stopWatch.Elapsed.TotalMilliseconds + "ms");
Console.ReadKey();
}
The simplest way is to do it using two shifts:
int xy = -123456;
// Split...
ushort m_X = (ushort) xy;
ushort m_Y = (ushort)(xy>>16);
// Convert back...
int back = (m_Y << 16) | m_X;
Demo on ideone: link.
int xy = 343423;
ushort low = (ushort)(xy & 0x0000ffff);
ushort high = (ushort)((xy & 0xffff0000) >> 16);
int xxyy = low + (((int)high) << 16);
I have a byte[] testKey = new byte[8];
This obviously starts with all bytes as 0. I want to go through all the bytes and increment by 1 on each iteration of the loop so eventually I go through all possibilities of the byte array. I also want to do this as FAST as possible. Yes I am trying to write a brute forcer.
Update I got the unsafe method working, and it is the quickest. However, by my calculations, it is going to take 76,000,000 years to loop through doing DES encryption on each key using the .Net DESCryptoServiceProvider. 10,000 encryptions takes 1.3 seconds. Thanks for all the awesome answers to the most useless question ever!
btw; it takes a lot of processing to check 2^64 options...
Well, the fastest way may be to just use an Int64 (aka long) or UInt64 (ulong), and use ++? Do you really need the byte[]?
As a hacky alternative, how about:
Array.Clear(data, 0, data.Length);
while (true)
{
// use data here
if (++data[7] == 0) if (++data[6] == 0)
if (++data[5] == 0) if (++data[4] == 0)
if (++data[3] == 0) if (++data[2] == 0)
if (++data[1] == 0) if (++data[0] == 0) break;
}
The only other approach I can think of would be to use unsafe code to talk to an array as though it is an int64... messy.
unsafe static void Test() {
byte[] data = new byte[8];
fixed (byte* first = data) {
ulong* value = (ulong*)first;
do {
// use data here
*value = *value + 1;
} while (*value != 0);
}
}
This is how you increase the value in the array:
int index = testKey.Length - 1;
while (index >= 0) {
if (testKey[index] < 255) {
testKey[index]++;
break;
} else {
testKey[index--] = 0;
}
}
When index is -1 after this code, you have iterated all combinations.
This will be slightly faster than using BitConverter, as it doesn't create a new array for each iteration.
Edit:
A small performance test showed that this is about 1400 times faster than using BitConverter...
What a great question! Here's a way to do it without unsafe code:
public struct LongAndBytes
{
[FieldOffset(0)]
public ulong UlongValue;
[FieldOffset(0)]
public byte Byte0;
[FieldOffset(1)]
public byte Byte1;
[FieldOffset(2)]
public byte Byte2;
[FieldOffset(3)]
public byte Byte3;
[FieldOffset(4)]
public byte Byte4;
[FieldOffset(5)]
public byte Byte5;
[FieldOffset(6)]
public byte Byte6;
[FieldOffset(7)]
public byte Byte7;
public byte[] ToArray()
{
return new byte[8] {Byte0, Byte1, Byte2, Byte3, Byte4, Byte5, Byte6, Byte7};
}
}
// ...
LongAndBytes lab = new LongAndBytes();
lab.UlongValue = 0;
do {
// stuff
lab.UlongValue++;
} while (lab.ULongValue != 0);
Each of the members Byte0...Byte7 overlap the ulong and share its members. It's not an array - I tried dinking around with that and had unsatisfactory results. I bet someone knows the magic declaration to make that happen. I can do that for a P/Invoke, but not for use in .NET as an array is an object.
byte[8] is essentially an ulong but if you really need it to be byte[8] you can use
byte[] bytes = new byte[8];
ulong i = 0;
bytes = BitConverter.GetBytes(i);
You can extract the bytes using bit operators:
byte[] bytes = new byte[8];
for (ulong u = 0; u < ulong.MaxValue; u++)
{
bytes[0] = (byte)(u & 0xff);
bytes[1] = (byte)((u >> 8) & 0xff);
bytes[2] = (byte)((u >> 16) & 0xff);
bytes[3] = (byte)((u >> 24) & 0xff);
bytes[4] = (byte)((u >> 32) & 0xff);
bytes[5] = (byte)((u >> 40) & 0xff);
bytes[6] = (byte)((u >> 48) & 0xff);
bytes[7] = (byte)((u >> 56) & 0xff);
// do your stuff...
}
This is less 'hackish', since it operates on an unsigned 64-bit integer first and then extract the bytes. However beware CPU endianess.
for (UInt64 i = 0; i < UInt64.MaxValue; i++)
{
byte[] data = BitConverter.GetBytes(i)
}
byte[] array = new byte[8];
int[] shifts = new int[] { 0, 8, 16, 24, 32, 40, 48, 56 };
for (long index = long.MinValue; index <= long.MaxValue; index++)
{
for (int i = 0; i < 8; i++)
{
array[i] = (byte)((index >> shifts[i]) & 0xff);
}
// test array
}
for (int i = 0; i < bytes.Length & 0 == ++bytes[i]; i++);
Should be as fast as the unsafe method and allows arrays of any size.
Simple iteration:
static IEnumerable<byte[]> Iterate(int arrayLength) {
var arr = new byte[arrayLength];
var i = 0;
yield return arr;
while (i < arrayLength)
{
if (++arr[i] != 0)
{
i = 0;
yield return arr;
}
else i++;
}
}
static void Main(string[] args)
{
foreach (var arr in Iterate(2))
{
Console.Write(String.Join(",", arr.Select(x => $"{x:D3}")));
Console.WriteLine();
}
}
Sorry for the late post, but I needed the described feature too and implemented it in a pretty easy way in my opinion. Maybe it's useful for somebody else too:
private byte[] IncrementBytes(byte[] bytes)
{
for (var i = bytes.Length - 1; i >= 0; i--)
{
if (bytes[i] < byte.MaxValue)
{
bytes[i]++;
break;
}
bytes[i] = 0;
}
return bytes;
}
BitConverter.ToInt64 / BitConverter.GetBytes - convert 8 byte to exactly long, and increment it.
When almost done convert back to bytes.
It is the fastest way in system