c# Remove specific bytes - c#

this might sound unclear but i know its difficult but we can remove specific bytes from byte[] array but if the array contain similiar values while removing values it can remove other values i m using :
byte[] B = new byte[] { 10, 0, 0, 10 };
byte[] D = new byte[] { 0, 0 };
byte[] NewArray = B.Except(D).ToArray();
BytesDisplayer.Text = String.Join(",", NewArray);
but lets say i have a byte as:
byte[] Data = new byte[] {0,10,10,10,0,5,5,5,10,10,10};
and i want to remove the last 3 values (10) My method will remove all the 10 value on that array , so basically i want to know is there is a way to remove specific bytes in specific indexes and how ?

try this:
byte[] Data = new byte[] { 0, 10, 10, 10, 0, 5, 5, 5, 10, 10, 10 };
Data = Data.Where((item, index) => index < 8).ToArray();

Related

Mock a method array argument using Moq

Using Moq4, I am trying to replace one of the method's argument as done with a List<string> on this post. However, using the byte[] type, I am not able to change the value. Any idea or solution?
The code
public class SomeObject
{
public virtual void DoSomething(byte[] array, int offset, int count) { }
}
[Fact]
public void SomeTest()
{
// Arrange
byte[] expectedArray = new byte[] { 5, 6, 7, 8, 9 };
var mock = new Mock<SomeObject>();
mock.Setup(so => so.DoSomething(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>()))
.Callback<byte[], int, int>(
(buffer, offset, count) => { buffer = new byte[] { 5, 6, 7, 8, 9 }; }
);
var target = mock.Object;
var array = new byte[64];
// Act
target.DoSomething(array, 0, 10);
// Assert
Assert.Equal(expectedArray, array);
}
Obtained output
Message:
Assert.Equal() Failure
Expected: Byte[] [5, 6, 7, 8, 9]
Actual: Byte[] [0, 0, 0, 0, 0, ...]
Assigning new byte[] { 5, 6, 7, 8, 9 }; to the lambda parameter creates a new object, which is different than the original byte[64] that you created beforehand.
The only way your lambda can modify the values passed by reference is using that reference, not replacing it. i.e: buffer[0] = 5.
If SomeObject is your own code (and you should not mock what you don't own), consider a signature that returns the array instead, in line with CQS. You could then just use .Returns() in this case.

C# - Converting from bits to Int32 generates wrong value

I am trying to convert an array of int values (each value representing a bit) to its representation as an Int32 object.
I have the following code:
//0000_0000_0000_0000_0000_0000_0000_1111 = 15
int[] numberData = new int[]
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1
};
//We convert our int[] to a bool[]
bool[] numberBits = numberData.Select(s => { return s == 0 ? false : true; }).ToArray();
//We generate a bit array from our bool[]
BitArray bits = new BitArray(numberBits);
//We copy all our bits to a byte[]
byte[] numberBytes = new byte[sizeof(int)];
bits.CopyTo(numberBytes, 0);
//We convert our byte[] to an int
int number = BitConverter.ToInt32(numberBytes, 0);
However, after executing this code, the value of number is -268435456.
Why does this happen?
The bit order is incorrect. -268435456 as a 32-bit integer is 11110000 00000000 00000000 00000000, which, as you can see, is exactly opposite what you wanted.
Just reverse your numberBits array before converting it to an Int32.
Alternatively, you could make numberData have the correct order and then never do any reversing.
Your code is working exactly how you wrote it. In numberData[0] is 0, numberData[1] is 0, ..., and numberData[31] is 1. This will cause bit 0 of your result to be 0, bit 1 to be 0, ..., and bit 31 to be 1.

Marshalling variable size packet

This question is somewhat extension of a question asked previously c# using marshalling for packet parsing by me.
I have to parse a variable size packet although header size is fixed but data packets inside it can be of different size and may be of more than 1 type are present in same packet.
For example the packet has following fields in its header :
1) username(12 bytes)
2 password(12 bytes)
3) id_number(4 bytes)
4) may be 1 or combination of other data packets of variable size(size can be 12, 16 or 512 bytes)
5) crc(2 bytes)
Now data packets can be following
a) data packet type 1
1) size(2 bytes)
2) name(12 bytes)
3) id_number(2 bytes)
b) data packet type 2
1) size(2 bytes)
2) data(24 bytes)
3) id_number(1 byte).
So there can be either type1 or type2. It is also possible for both type to be present. My question is how can I use marshalling to parse these packets or anyone can suggest some other way.
One more thing I want to add is that 1st and 3rd field of data packets will always be the data packet size(2 bytes) and data packet id number(1 byte) respectively. The 2nd field of data packets can be anything and of variable size(2, 3, 13, 18, 515).
As an alternative, you may use LINQ (assuming that ASCII encoding is being used):
var packet = new byte[]{
97, 108, 101, 120, 0, 0, 0, 0, 0, 0, 0, 0, // username
112, 97, 115, 115, 119, 111, 114, 100, 0, 0, 0, 0, //password
49, 50, 51, 0, // id_number
0, 53, 0, 0, 1, // 1st data packet
0, 54, 1, 2, 5, 2, // 2nd data packet
49, 0 // crc
};
var username = Encoding.ASCII.GetString(packet.Take(12).ToArray());
var password = Encoding.ASCII.GetString(packet.Skip(12).Take(12).ToArray());
var idNumber = Encoding.ASCII.GetString(packet.Skip(24).Take(4).ToArray());
var data = packet.Skip(28).Take(packet.Length - 30).ToArray();
var crc = Encoding.ASCII.GetString(packet.Skip(packet.Length - 2).ToArray());
var nextDataPackedPos = 0;
var nextDataPackedPos = 0;
var dataPackets = data
.TakeWhile(b => nextDataPackedPos < data.Length)
.Zip(data.Skip(nextDataPackedPos), (a, b) =>
{
var size = Int32.Parse(
Encoding.ASCII
.GetString(data.Skip(nextDataPackedPos).Take(2).ToArray())
.Trim('\0')
);
var result = data.Skip(nextDataPackedPos).Take(size).ToArray();
nextDataPackedPos += size;
return result;
}).ToList();
The code first separates the data section from the packet bytes. Then it reads the size of each packet and based on it, it creates an equaly sized array containing the bytes of the data packet. It hen advances to the beginning of the next packet until the end of the array is reached.

how to append zero's to array which is already having a binary values

I have a decimal value of 126 which is converted to binary value using the below code:
binary[i] = Convert.ToString(bmparrayelement[i], 2);
then I got the value as "111 1110" which is right.
Then I want to append zeros along with this value in prefix that is "00 0111 1110"
Try something like this:-
string s1 = Convert.ToString(byteArray[20], 2).PadLeft(10, '0');
Sorry if I have misunderstood but why can't you just do the below?
binary[i] = "00 0" + Convert.ToString(bmparrayelement[i], 2);
Try this:
var binary = new byte[] {1, 1, 1, 1, 1, 1, 0};
var zeroed = new byte[] {0, 0};
binary = zeroed.Concat(binary).ToArray();
Update
In .net 2.0 you can use:
const int number = 2;
var binary = new byte[] {1, 1, 1, 1, 1, 1, 0};
var a = new byte[binary.Length + number];
binary.CopyTo(a, number);
binary = a;

How can I implement CBC-MAC with DES?

I should implement a MAC-CBC generation method in C# with some information about the cryptography algorithm. Here's what I have:
I should use DES.
The key is byte[] {11, 11, 11, 11, 11, 11, 11, 11}
The data (16 bytes) should be encrypted in 8-byte parts. First 8 bytes is encrypted using Instance Vector = new byte[8] (8 bytes with 0 value). (CBC?)
that last 8 bytes of the encrypted value should be converted to Hex string. this is the result I should send.
With this information, I have implemented the following method:
public static string Encrypt(byte[] data)
{
var IV = new byte[8];
var key = new byte[] { 11, 11, 11, 11, 11, 11, 11, 11 };
var result = new byte[16];
// Create DES and encrypt.
var des = DES.Create();
des.Key = key;
des.IV = IV;
des.Padding = PaddingMode.None;
des.Mode = CipherMode.CBC;
ICryptoTransform cryptoTransform = des.CreateEncryptor(key, IV);
cryptoTransform.TransformBlock(data, 0, 16, result, 0);
// Get the last eight bytes of the encrypted data.
var lastEightBytes = new byte[8];
Array.Copy(result, 8, lastEightBytes, 0, 8);
// Convert to hex.
var hexResult = string.Empty;
foreach (byte ascii in lastEightBytes)
{
int n = (int)ascii;
hexResult += n.ToString("X").PadLeft(2, '0');
}
return hexResult;
}
The sample raw data they have provided me is: input=byte[] {0, 6, 4, 1, 6, 4, 1, 7, E, E, F, F, F, F, B, B) which should return the output of value: A7CBFB3C730B059C. This means the last eight bytes of encrypted data should be: byte[] {167, 203, 251, 60, 115, 11, 05, 156}.
But unfortunately using the above method, I get: 32D91200D0007632. meaning my encrypted data is not correct. (the last eight byte of my method's generated encrypted value is byte[] {50, 207, 18, 0, 208, 0, 118, 50}).
Is there any way that I can find out what I should do to get to A7CB...? Am I doing something wrong?
CBC-MAC requires a zero Initialisation Vector. Much better to specify the IV explicitly:
var IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
You say your key is byte[] { 11, 11, 11, 11, 11, 11, 11, 11 } are those bytes in hex or in base 10? You might want to try:
var key = new byte[] { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 };
and see if that works better.
The Mono project has a generic MAC-CBC implementation that should work on any SymmetricAlgorithm - even if it's used, internally, only to implement MACTripleDES.
You can find the MIT.X11 licensed source code here. Use it as-is or compare it to your own code.

Categories

Resources