How to make faster a for Loop when Iterating between Bytes? - c#

Greatings, everybody! I'm making a small tool that Encrypts the Data of a File by Xoring all its bytes and after that, Encoding the Xor Result by using Base64. The problem begins when Looping between each Byte contained inside the File Data, this is how I've done:
int Initialization_Vector_Size = Initialization_Vector.Length;
string Crypto_String = null;
for(int Index = 0; Index < Input_Data_Size; Index++)
{
int Single_Index = Index;
byte Single_Byte = Input_Data[Single_Index];
char Input_Character = Convert.ToChar(Single_Byte);
int Input_Character_Code = (int)Input_Character;
int Key_Index = Single_Index % Cipher_Key_Size;
char Key_Character = Cipher_Key[Key_Index];
int Cipher_Key_Code = (int)Key_Character;
int Xor_Value = Input_Character_Code ^ Cipher_Key_Code;
int IV_Index = Single_Index % Initialization_Vector_Size;
char IV_Character = Initialization_Vector[IV_Index];
int Initialization_Vector_Code = (int)IV_Character;
int Crypto_Character_Code = Xor_Value ^ Initialization_Vector_Code;
char Crypto_Character = (char)Crypto_Character_Code;
char[] Characters_List = {Crypto_Character};
string Security_Code = new String(Characters_List);
Crypto_String += Security_Code;
}
byte[] Encrypted_Data = Encoding.ASCII.GetBytes(Crypto_String);```

Related

RC4 encrypting data when knowing how to decrypt it

Im currently working with an online API that sends me some users with a encrypted PIN that is encrypted with RC4. its sent in Hex(8) and ive managed to decrypt the hex into the int that it originally was, but i cant for the life of me reverse it to send an encrypted pin(is 4 digits long, pre enc) back. im not the sharpest tool in the shed when it comes to crypt especially not when its between data types so im hoping someone is abit more experianced.
My Classes for RC4:
Decrypt Function:
public string DecryptUserPin(Users user)
{
try
{
byte[] out_ = new byte[8];
crypto crypto = new crypto((long)user.UID);
byte[] bytes = BitConverter.GetBytes(int.Parse(user.PIN, NumberStyles.HexNumber));
crypto.crypto_rc4(ref bytes, ref out_, (long)bytes.Length);
return BitConverter.ToInt64(out_, 0).ToString();
}
catch (Exception ex)
{
Console.WriteLine("ERROR" + ex.ToString());
return (string)null;
}
}
Crypto class:
public class crypto
{
private string key = "Secret words ";
public rc4_key_t ctx;
public crypto(long userId)
{
this.key += userId.ToString();
byte length = (byte)this.key.Length;
byte[] numArray = new byte[256];
for (short index = 0; index < (short)256; ++index)
numArray[(int)index] = (byte)index;
this.ctx.x = (byte)0;
this.ctx.y = (byte)0;
byte index1 = 0;
byte index2 = 0;
for (short index3 = 0; index3 < (short)256; ++index3)
{
index2 = (byte)((int)this.key[(int)index1] + (int)numArray[(int)index3] + (int)index2 & (int)byte.MaxValue);
byte num = numArray[(int)index3];
numArray[(int)index3] = numArray[(int)index2];
numArray[(int)index2] = num;
index1 = (byte)(((uint)index1 + 1U) % (uint)length);
}
this.ctx.state = numArray;
}
public void crypto_rc4(ref byte[] in_, ref byte[] out_, long len)
{
byte index1 = this.ctx.x;
byte index2 = this.ctx.y;
byte[] numArray = new byte[8];
byte[] state = this.ctx.state;
for (short index3 = 0; (long)index3 < len; ++index3)
{
index1 = (byte)((int)index1 + 1 & (int)byte.MaxValue);
index2 = (byte)((int)state[(int)index1] + (int)index2 & (int)byte.MaxValue);
byte num1 = state[(int)index1];
state[(int)index1] = state[(int)index2];
state[(int)index2] = num1;
byte index4 = (byte)((int)state[(int)index1] + (int)state[(int)index2] & (int)byte.MaxValue);
byte num2 = (byte)((uint)in_[(int)index3] ^ (uint)state[(int)index4]);
numArray[(int)index3] = num2;
}
this.ctx.x = index1;
this.ctx.y = index2;
out_ = numArray;
}
}
Support Class:
public struct rc4_key_t
{
public byte[] state;
public byte x;
public byte y;
}

C# How to fix loss of data during file to binary to string to binary conversion

I read a file as binary, convert to hex string, convert back to binary, and write to a new file.
I expect a duplicate, but get a corrupted file.
I have been trying different ways to convert the binary into the hex string but can't seem to retain the entire file.
byte[] binary1 = File.ReadAllBytes(#"....Input.jpg");
string hexString = "";
int counter1 = 0;
foreach (byte b in binary1)
{
counter1++;
hexString += (Convert.ToString(b, 16));
}
List<byte> bytelist = new List<byte>();
int counter2 = 0;
for (int i = 0; i < hexString.Length/2; i++)
{
counter2++;
string ch = hexString.Substring(i*2,2);
bytelist.Add(Convert.ToByte(ch, 16));
}
byte[] binary2 = bytelist.ToArray();
File.WriteAllBytes(#"....Output.jpg", binary2);
Counter 1 and counter 2 should be the same count, but counter 2 is always about 10% smaller.
I want to get a duplicate file output that I could have transferred around via that string value.
Converting byte 10 will give a single char, and not 2 characters. Your convert back method (logically) build on 2 chars per byte.
this case works
byte[] binary1 = new byte[] { 100 }; // convert will result in "64"
and this case fails
byte[] binary1 = new byte[] { 10 }; // convert will result in "a"
I quick fixed your code, by padding with a "0" in case of a single char.
so working code:
byte[] binary1 = new byte[] { 100 };
string hexString = "";
int counter1 = 0;
foreach (byte b in binary1)
{
counter1++;
var s = (Convert.ToString(b, 16));
// new
if (s.Length < 2)
{
hexString += "0";
}
// end new
hexString += s;
}
List<byte> bytelist = new List<byte>();
int counter2 = 0;
for (int i = 0; i < hexString.Length / 2; i++)
{
counter2++;
string ch = hexString.Substring(i * 2, 2);
var item = Convert.ToByte(ch, 16);
bytelist.Add(item);
}
byte[] binary2 = bytelist.ToArray();
Please note, your code could use some refactoring, e.g. don't string concat in a loop and maybe check the Single Responsibility Principle.
Update, got it fixed, but there are better solutions here: How do you convert a byte array to a hexadecimal string, and vice versa?

C# hex to byte array loop

I have the following function:
public void SetTagData(string _data)
{
string data = _data;
byte[] ba = Encoding.Default.GetBytes(data);
string hexString = BitConverter.ToString(ba);
hexString = hexString.Replace("-", "");
var blockStart = 0;
var bufferHexBlocks = String.Empty;
try
{
for (var i = 0; i < hexString.Length; i++)
{
var byteList = new List<byte>();
byte[] datablockKey = ConvertHelpers.ConvertHexStringToByteArray(i.ToString().PadLeft(2, '0'));
var block = hexString.Substring(blockStart, 8);
byte[] datablockValue = ConvertHelpers.ConvertHexStringToByteArray(block);
byteList.AddRange(datablockKey);
byteList.AddRange(datablockValue);
_reader.Protocol("wb", byteList.ToArray());
blockStart += 8;
}
}
catch (Exception ex)
{
console.log(ex.message);
}
}
The data coming in is a bunch of hex as a string. I need to split this hex string into batches of 8 characters, append an incrementing 0 padded hex number from 00 to 1f and send this new string as a byte array to the _reader.Protocol function, which accepts a string wb as first parameter and the block as the second.
For example incoming data is:
string data = "3930313B36313B5350542D53504C3B3830303B3B352E373B3B303B303B3B3B34353036383B4E3B4E3B"
I need to send the following to the _reader.Protocol object:
(incremented padded hex 01, 02, 03, ... , 0f) and the first 8 characters of the data string, then the next, and so on as a byte array.
[013930313B], [0236313B53], etc.
I think I'm getting close... but missing something...
My problem at the moment is that I can't figure out how to loop in blocks of 8 and if the hex string is say 82 characters instead of 80 (multiple of 8), then how would I grab the last two characters without getting a IndexOutofRange exception.
Note: This is for a Windows CE application, so no new C# features please.
This below will work fine in conjunction with this answer and the sample string data given.
public static byte[] Parse(string data)
{
var count = data.Length / 8; //Might be worth throwing exception with any remainders unless you trust the source.
var needle = 0;
List<byte> result = new List<byte>(); //Inefficient but I'm being lazy
for (int i = 0; i < count; i++)
{
char[] buffer = new char[8];
data.CopyTo(needle, buffer, 0, buffer.Length);
//To get around the odd number when adding the prefixed count byte, send the hex string to the convert method separately.
var bytes = ConvertHexStringToByteArray(new string(buffer)); //Taken From https://stackoverflow.com/a/8235530/6574422
//As the count is less than 255, seems safe to parse to single byte
result.Add(byte.Parse((i + 1).ToString()));
result.AddRange(bytes);
needle += 8;
}
return result.ToArray();
}
I'm figured it out. It might not be the most efficient solution but it works just fine. I did it using a for loop inside a for loop.
In case anyone is interested here is the final code:
public void SetTagData(string _data)
{
string data = _data;
byte[] ba = Encoding.Default.GetBytes(data);
string hexString = BitConverter.ToString(ba);
hexString = hexString.Replace("-", "");
var blockStart = 0;
try
{
_reader.Protocol("s");
for(var count = 0; count < 16; count++)
{
var byteList = new List<byte>();
byte[] datablockKey = ConvertHelpers.ConvertHexStringToByteArray(count.ToString("X2"));
byteList.AddRange(datablockKey);
for (var innerCount = 0; innerCount < 4; innerCount++)
{
var block = String.Empty;
if (!String.IsNullOrEmpty(hexString.Substring(blockStart, 2)))
{
block = hexString.Substring(blockStart, 2);
}
else
{
block = "20";
}
byte[] datablockValue = ConvertHelpers.ConvertHexStringToByteArray(block);
byteList.AddRange(datablockValue);
blockStart += 2;
}
_reader.Protocol("wb", byteList.ToArray());
}
}
catch (Exception)
{
}
}

Problems with converting char array to string

I have a function in a small application that I'm writing to break a recycled one-time pad cypher. Having used VB.NET for most of my career I thought it would be interesting to implement the app in C#. However, I have encountered a problem due to my present unfamiliarity with C#.
The function takes in two strings (of binary digits), converts these strings to char arrays, and then performs an XOR on them and places the result in a third char array.
This is fine until I try to convert the third char array to a string. Instead of the string looking like "11001101" etc, I get the following result: " \0\0 \0 " i.e. the "1"s are being represented by spaces and the "0"s by "\0".
My code is as follows:
public string calcXor(string a, string b)
{
char[] charAArray = a.ToCharArray();
char[] charBArray = b.ToCharArray();
int len = 0;
// Set length to be the length of the shorter string
if (a.Length > b.Length)
len = b.Length - 1;
else
len = a.Length - 1;
char[] result = new char[len];
for (int i = 0; i < len; i++)
{
result[i] = (char)(charAArray[i] ^ charBArray[i]);
}
return new string(result);
}
Your problem is in the line
result[i] = (char)(charAArray[i] ^ charBArray[i]);
that should be
// (Char) 1 is not '1'!
result[i] = (char)((charAArray[i] ^ charBArray[i]) + '0');
More compact solution is to use StringBuilder, not arrays:
public string calcXor(String a, String b) {
int len = (a.Length < b.Length) ? a.Length : b.Length;
StringBuilder Sb = new StringBuilder();
for (int i = 0; i < len; ++i)
// Sb.Append(CharToBinary(a[i] ^ b[i])); // <- If you want 0's and 1's
Sb.Append(a[i] ^ b[i]); // <- Just int, not in binary format as in your solution
return Sb.ToString();
}
public static String CharToBinary(int value, Boolean useUnicode = false) {
int size = useUnicode ? 16 : 8;
StringBuilder Sb = new StringBuilder(size);
Sb.Length = size;
for (int i = size - 1; i >= 0; --i) {
Sb[i] = value % 2 == 0 ? '0' : '1';
value /= 2;
}
return Sb.ToString();
}
Your solution just computes xor's (e.g. "65") and put them into line (e.g. 65728...); if you want 0's and 1's representation, you should use formatting
Have a look at the ASCII Table. 0 is the Null character \0. You could try ToString()
Have you tried using binary / byte[]? It seems like the fastest way to me.
public string calcXor(string a, string b)
{
//String to binary
byte[] ab = ConvertToBinary(a);
byte[] bb = ConvertToBinary(b);
//(XOR)
byte[] cb = a^b
return cb.ToString();
}
public static byte[] ConvertToBinary(string str)
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
return encoding.GetBytes(str);
}
I just wanted to add that the solution I eventually chose is as follows:
//Parameter binary is a bit string
public void someroutine(String binary)
{
var data = GetBytesFromBinaryString(binary);
var text = Encoding.ASCII.GetString(data);
}
public Byte[] GetBytesFromBinaryString(String binary)
{
var list = new List<Byte>();
for (int i = 0; i < binary.Length; i += 8)
{
String t = binary.Substring(i, 8);
list.Add(Convert.ToByte(t, 2));
}
return list.ToArray();
}

Dotnet Hex string to Java

Have a problem, much like this post: How to read a .NET Guid into a Java UUID.
Except, from a remote svc I get a hex str formatted like this: ABCDEFGH-IJKL-MNOP-QRST-123456.
I need to match the GUID.ToByteArray() generated .net byte array GH-EF-CD-AB-KL-IJ-OP-MN- QR- ST-12-34-56 in Java for hashing purposes.
I'm kinda at a loss as to how to parse this. Do I cut off the QRST-123456 part and perhaps use something like the Commons IO EndianUtils on the other part, then stitch the 2 arrays back together as well? Seems way too complicated.
I can rearrange the string, but I shouldn't have to do any of these. Mr. Google doesn't wanna help me neither..
BTW, what is the logic in Little Endian land that keeps those last 6 char unchanged?
Yes, for reference, here's what I've done {sorry for 'answer', but had trouble formatting it properly in comment}:
String s = "3C0EA2F3-B3A0-8FB0-23F0-9F36DEAA3F7E";
String[] splitz = s.split("-");
String rebuilt = "";
for (int i = 0; i < 3; i++) {
// Split into 2 char chunks. '..' = nbr of chars in chunks
String[] parts = splitz[i].split("(?<=\\G..)");
for (int k = parts.length -1; k >=0; k--) {
rebuilt += parts[k];
}
}
rebuilt += splitz[3]+splitz[4];
I know, it's hacky, but it'll do for testing.
Make it into a byte[] and skip the first 3 bytes:
package guid;
import java.util.Arrays;
public class GuidConvert {
static byte[] convertUuidToBytes(String guid) {
String hexdigits = guid.replaceAll("-", "");
byte[] bytes = new byte[hexdigits.length()/2];
for (int i = 0; i < bytes.length; i++) {
int x = Integer.parseInt(hexdigits.substring(i*2, (i+1)*2), 16);
bytes[i] = (byte) x;
}
return bytes;
}
static String bytesToHexString(byte[] bytes) {
StringBuilder buf = new StringBuilder();
for (byte b : bytes) {
int i = b >= 0 ? b : (int) b + 256;
buf.append(Integer.toHexString(i / 16));
buf.append(Integer.toHexString(i % 16));
}
return buf.toString();
}
public static void main(String[] args) {
String guid = "3C0EA2F3-B3A0-8FB0-23F0-9F36DEAA3F7E";
byte[] bytes = convertUuidToBytes(guid);
System.err.println("GUID = "+ guid);
System.err.println("bytes = "+ bytesToHexString(bytes));
byte[] tail = Arrays.copyOfRange(bytes, 3, bytes.length);
System.err.println("tail = "+ bytesToHexString(tail));
}
}
The last group of 6 bytes is not reversed because it is an array of bytes. The first four groups are reversed because they are a four-byte integer followed by three two-byte integers.

Categories