I am reading a file into a byte array and converting the byte array into a string to pass into a method(I cant pass the byte array itself) and in the function definition I am reconverting the string to byte array. but both the byte arrays( before and after conversion are different)
I am using the following pilot code to test if byte arrays are same.
byte[] bytes = File.ReadAllBytes(#"C:\a.jpg");
string encoded = Convert.ToBase64String(bytes);
byte[] bytes1 = Encoding.ASCII.GetBytes(encoded);
When I use bytes in the api call, it succeds and when I use bytes1 it throws an exception. Please tell me how can I safely convert the byte array to string and back such that both arrays reman same.
Use this:
byte[] bytes = File.ReadAllBytes(#"C:\a.jpg");
string encoded = Convert.ToBase64String(bytes);
byte[] bytes1 = Convert.FromBase64String(encoded);
I'll post a response from another thread:
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
static string GetString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
full thread here: How do I get a consistent byte representation of strings in C# without manually specifying an encoding?
Related
Example, I want to convert 3 bytes to ASCII conversion
int a = random.Next(0, 100);
int b = random.Next(0, 1000);
int c = random.Next(0, 30);
byte[] byte1 = BitConverter.GetBytes(a);
byte[] byte2 = BitConverter.GetBytes(b);
byte[] byte3 = BitConverter.GetBytes(c);
byte[] bytes = byte1.Concat(byte2).Concat(byte3).ToArray();
string asciiString = Encoding.ASCII.GetString(bytes, 0, bytes.Length);
label1.Text = asciiString;
It only shows byte1 instead of all bytes.
If you look in the debugger at your asciiString variable you will see that all the 3 letters are there, but in between you always have a 0x00 char.
(screenshot from LINQPad Dump)
This is unfortunately interpreted as end of string. So this is why you see only the first byte/letter.
The documentation of GetBytes(char) says that it returns:
An array of bytes with length 2.
if you now get the bytes from a single char:
byte[] byte1 = BitConverter.GetBytes('a');
You get the following result:
The solution would be to pick only the bytes that are not 0x00:
bytes = bytes.Where(x => x != 0x00).ToArray();
string asciiString = Encoding.ASCII.GetString(bytes, 0, bytes.Length);
label1.Text = asciiString;
This example is based on the char variant of GetBytes. But it holds for all other overloads of this method. They all return an array which can hold the maximum value of the corresponding data type. So this will happen always if the value is so small that the last byte in the array is not used and ends up to be 0!
I'm using the .net port of libsodium. The hash generation function has two forms, one that accepts byte arrays and one that accepts strings:
public static byte[] ArgonHashBinary(string password, string salt, long opsLimit, int memLimit, long outputLength = ARGON_SALTBYTES)
public static byte[] ArgonHashBinary(byte[] password, byte[] salt, long opsLimit, int memLimit, long outputLength = ARGON_SALTBYTES)
What i'm having an issue with is both forms producing the same hash when the input values are identical.
var saltAsBytes = PasswordHash.ArgonGenerateSalt();
var saltAsString = Encoding.UTF8.GetString(saltAsBytes);
var tmp = Encoding.UTF8.GetBytes(saltAsString);
var hash1 = PasswordHash.ArgonHashBinary(password, saltAsString, 6, 134217728, 16);
var hash2 = PasswordHash.ArgonHashBinary( Encoding.UTF8.GetBytes(password), saltAsBytes, 6, 134217728, 16);
Anything with "PasswordHash." is libsodium and not my code.
From the code above when i convert it from a string and then back to a byte array the byte array. The byte array array is always a different length. ArgonGenerateSalt() produces a byte array with a length of 16. When i convert it back from a string above its generally ~30 (different every time because of different salts produced).
Why am i converting to UTF8? Because thats what they are doing internally:
https://github.com/adamcaudill/libsodium-net/blob/master/libsodium-net/PasswordHash.cs
public static byte[] ArgonHashBinary(string password, string salt, StrengthArgon limit = StrengthArgon.Interactive, long outputLength = ARGON_SALTBYTES)
{
return ArgonHashBinary(Encoding.UTF8.GetBytes(password), Encoding.UTF8.GetBytes(salt), limit, outputLength);
}
When i convert the salt to a UTF8 string the hashing function will fail because they are checking the length of the byte array to make sure its 16 bytes. If i convert it to a ASCII string it works but produces a different hash (which is expected).
To clarify the hashing piece in this code is not the issue. Figuring out why tmp is different then saltAsBytes is the key.
I think the problem here is that the ArgonGenerateSalt method doesn't return a UTF8 encoded string, it returns completely random bytes.
You can't decode random bytes as a UTF8 string and expect it to round trip. A trivial example to see where this blows up is to do the following:
var data = new byte[] { 128 };
var dataAsString = Encoding.UTF8.GetString( data );
var dataAsBytes = Encoding.UTF8.GetBytes( dataAsString );
After this, dataAsBytes will be 3 bytes (specifically 239, 191, 189).
Converting a byte array to string and then back again produced different results
A binary data may not be converted to string and then back to byte array
using Encoding.[AnyEncoding].GetBytes and Encoding.[AnyEncoding].GetString
Instead use Convert.ToBase64String and Convert.FromBase64String
You can easily test...
var bytes = new byte[] { 255, 255, 255 };
var buf = Encoding.UTF8.GetString(bytes);
var newbytes = Encoding.UTF8.GetBytes(buf);
newbytes's length will be 9.....
Edit: This is the test case for #Theo
var bytes = new byte[] { 0, 216 }; //any new byte[] { X, 216 };
var buf = Encoding.Unicode.GetString(bytes);
var newbytes = Encoding.Unicode.GetBytes(buf); //253,255
I am getting an error reading:
Cannot implicitly convert type 'String' to 'Byte[]'
I think 'byte[]' is byte array - if it isn't please correct me.
I have tried another solution on this website but I did not understand. I'm making a c# 'RTM tool' and this is what put in :
byte[] bytes = (metroTextBox2.Text);
Array.Resize<byte>(ref bytes, bytes.Length + 1);
PS3.SetMemory(0x2708238, bytes);
You can try like this:
string str= "some string";
var bytes = System.Text.Encoding.UTF8.GetBytes(str);
And to decode:
var decodeString = System.Text.Encoding.UTF8.GetString(bytes);
static void Main(string[] args)
{
string inputStr = Console.ReadLine();
byte[] bytes = Encoding.Unicode.GetBytes(inputStr);
string str = Encoding.Unicode.GetString(bytes);
Console.WriteLine(inputStr == str); // true
}
Try this,
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
n byte to string conversion
static string GetString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
Credit to this answer.
currently I am testing a script that tries to save an image file converted from a string of HEX, however, when I try to execute the Save command, parameter not valid appears.
// Some junk hex image data
string hexImgData = #"FFD8FFE000104A46494600010200006400640000FFFFD9";
// Call function to Convert the hex data to byte array
byte[] newByte = ToByteArray(hexImgData);
MemoryStream memStream = new MemoryStream(newByte);
// Save the memorystream to file
Bitmap.FromStream(memStream).Save("C:\\img.jpg");
// Function converts hex data into byte array
public static byte[] ToByteArray(String HexString)
{
int NumberChars = HexString.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
{
bytes[i / 2] = Convert.ToByte(HexString.Substring(i, 2), 16);
}
return bytes;
}
Currently I am still in the process of looking what causes this, please advice.
As was mentioned in the comments, your bitmap format is wrong, all you have is some random hex data and the Bitmap.FromStream method has no idea what to do with it. If you look at this link which discusses how to create a bitmap file with a hex editor it discusses the BitmapHeader, BitmapInfoHeader, and the Pixel RGB Data. I was able to create a bitmap using your code by taking the data from their example and using it.
string bitmapHeader = "424D860000000000000036000000";
string bitmapInfoHeader = "280000000500000005000000010018000000000050000000C40E0000C40E00000000000000000000";
string pixelData = "0000FF0000FF0000FF0000FF0000FF000000FF0000FF0000FF0000FF0000FF000000FF0000FF0000FF0000FF0000FF000000FF0000FF0000FF0000FF0000FF000000FF0000FF0000FF0000FF0000FF00";
string hexImgData = bitmapHeader + bitmapInfoHeader + pixelData;
// Call function to Convert the hex data to byte array
byte[] newByte = ToByteArray(hexImgData);
MemoryStream memStream = new MemoryStream(newByte);
pictureBox1.Image = Bitmap.FromStream(memStream);
It seems you need convert incoming string from Base64 to byte array like this:
byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);
This is my code:
byte[] base64String = //this is being set properly
var base64CharArray = new char[base64String.Length];
Convert.ToBase64CharArray(base64String,
0,
base64String.Length,
base64CharArray,
0);
var Base64String = new string(base64CharArray);
When i run this, I get the following error when calling Convert.ToBase64CharArray:
Either offset did not refer to a position in the string, or there is an insufficient length of destination character array. Parameter name: offsetOut
How do i fix this, so i can convert my byte array to a string, or is there a better way to convert a byte array to a string?
Why do you need the char array? Just convert your byte[] directly to a Base64 string:
string base64String = Convert.ToBase64String(myByteArray);
base64 encoding needs 4 characters to encode 3 bytes of input. you have to enlarge your output array.
here is one way you can convert byte array to string
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
static string GetString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
you don't really need to worry about encoding.
more details can be found here
This is a simple form of doing it
string System.Text.Encoding.UTF8.GetString(YourbyteArray)