I have the following code to encode a plain text:
int AddNumber;
int AsciiNumber;
string OneChar;
string String1 = "DAVE SMITH";
string String2 = "";
for (int i = 0; i < String1.Length; i++)
{
AddNumber = i + 95;
AsciiNumber = (int)Char.Parse(String1.Substring(i,1));
byte[] NewAscii = new byte[] { Convert.ToByte( AsciiNumber + AddNumber ) };
// Get string of the NewAscii
OneChar = Encoding.GetEncoding(1252).GetString(NewAscii);
String2 = String2 + OneChar;
}
The problem I have is how to decode the string back to plain text. Here is my attempt code:
String1 = "";
for (int i = 0; i < String2.Length; i++)
{
AddNumber = i + 95;
AsciiNumber = (int)Char.Parse(String2.Substring(i,1));
byte[] NewAscii = new byte[] { Convert.ToByte( AsciiNumber - AddNumber ) };
// Get string of the NewAscii
OneChar = Encoding.GetEncoding(1252).GetString(NewAscii);
String1 = String1 + OneChar;
}
The problem is that above, on processing the encoded empty space (between DAVE and SMITH), the value AsciiNumber = (int)Char.Parse(String2.Substring(i,1)) is 402 where it should be 131.
Do you see what I am misunderstanding?
By adding 95 to a space (ASCII 36) you end up with byte 131. You then ask for the Windows-1252 text at 131, which is a Latin ƒ and store that into C#'s native Unicode string. C# is going to map that Latin ƒ back to UTF-16 for storage into memory. Later, you ask for that character back - it's Unicode code point is U+0192; convert that from hex and you get decimal 402. Trying to get that back to Windows-1252 will obviously fail, since it's not a byte.
What you probably want to do, is to use Encoding.GetBytes to have the Unicode text converted to Windows-1252 before manipulating the characters.
For the decoding part
String1 = "";
for (int i = 0; i < String2.Length; i++)
{
var charByte = System.Text.Encoding.GetEncoding(1252).GetBytes(String2.Substring(i, 1));
AddNumber = i + 95;
AsciiNumber = Convert.ToInt32(charByte[0]) - AddNumber;
String1 += Convert.ToChar(AsciiNumber);
}
Related
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?
I have a text message i have converted to ASCII. I've then used the ASCII value and a keyword to convert the ASCII value to that of its corresponding letter in a unique alphabet. How would i convert the ASCII number back into a character. I currently am using characteres 97 - 122
foreach (char c in txtEncryption.Text) // Finding ascii values for each character
{
byte[] TempAsciiValue = Encoding.ASCII.getChars(c); // Fix,,,
string TempAsciiValStr = TempAsciiValue.ToString();
int TempAsciiVal = int.Parse(TempAsciiValStr);
if (TempAsciiVal == 32)
{
ArrayVal[Count] = TempAsciiVal;
}
else
{
// Calculations
int Difference = TempAsciiVal - 65; // Finds what letter after A it is
int TempValue = ArrayAlphabet[Count, 1]; // Find the starting ASCII value for new alphabet
int TempValuePlusDifference = TempValue + Difference;
//Convert the ASCII value to the letter
ArrayVal[Count] = TempValuePlusDifference; //Store the letters ASCII code
Count++;
if (Count > 3)
{
Count = 1;
}
}
for (int d = 1; d < CountMessageLength; d++)
{
string TempArrayVal = ArrayVal[Count].ToString();
txtEncryption2.Text = TempArrayVal;
// Convert TempArrayVal to = Letter (TempLetterStorage),,,,
// String FinalMessage = all TempLetterStorage values
}
}
Starting with bytes that are ASCII character codes, say for the sake of this exercise, 97 to 122
Byte[] asciiBytes = Enumerable.Range(97, 122 + 1 - 97).Select(i => (Byte)i).ToArray();
Use an encoding object for the ASCII encoding, with desirable behaviors, to whit: validate our assumption that the input character codes are in the ASCII range:
Encoding asciiEncoding = Encoding.GetEncoding(
Encoding.ASCII.CodePage,
EncoderFallback.ExceptionFallback,
DecoderFallback.ExceptionFallback)
Decode to a .NET String (UTF-16)
String text = asciiEncoding.GetString(asciiBytes);
I have a unicode string like this:
0030003100320033
Which should turn into 0123.
This is a simple case of 0123 string, but there are some string and unicode chars as well. How can I turn this type of unicode hex string to string in C#?
For normal US charset, first part is always 00, so 0031 is "1" in ASCII, 0032 is "2" and so on.
When its actual unicode char, like Arabic and Chinese, first part is not 00, for instance for Arabic its 06XX, like 0663.
I need to be able to turn this type of Hex string into C# decimal string.
There are several encodings that can represent Unicode, of which UTF-8 is today's de facto standard. However, your example is actually a string representation of UTF-16 using the big-endian byte order. You can convert your hex string back into bytes, then use Encoding.BigEndianUnicode to decode this:
public static void Main()
{
var bytes = StringToByteArray("0030003100320033");
var decoded = System.Text.Encoding.BigEndianUnicode.GetString(bytes);
Console.WriteLine(decoded); // gives "0123"
}
// https://stackoverflow.com/a/311179/1149773
public static byte[] StringToByteArray(string hex)
{
byte[] bytes = new byte[hex.Length / 2];
for (int i = 0; i < hex.Length; i += 2)
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
return bytes;
}
Since Char in .NET represents a UTF-16 code unit, this answer should give identical results to Slai's, including for surrogate pairs.
Shorter less efficient alternative:
Regex.Replace("0030003100320033", "....", m => (char)Convert.ToInt32(m + "", 16) + "");
You should try this solution
public static void Main()
{
string hexString = "0030003100320033"; //Hexa pair numeric values
//string hexStrWithDash = "00-30-00-31-00-32-00-33"; //Hexa pair numeric values separated by dashed. This occurs using BitConverter.ToString()
byte[] data = ParseHex(hexString);
string result = System.Text.Encoding.BigEndianUnicode.GetString(data);
Console.Write("Data: {0}", result);
}
public static byte[] ParseHex(string hexString)
{
hexString = hexString.Replace("-", "");
byte[] output = new byte[hexString.Length / 2];
for (int i = 0; i < output.Length; i++)
{
output[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
}
return output;
}
I am writing a winform to convert written text into Unicode numbers and UTF8 numbers. This bit is working well
//------------------------------------------------------------------------
// Convert to UTF8
// The return will be either 1 byte, 2 bytes or 3 bytes.
//-----------------------------------------------------------------------
UTF8Encoding utf8 = new UTF8Encoding();
StringBuilder builder = new StringBuilder();
string utext = rchtxbx_text.Text;
// do one char at a time
for (int text_index = 0; text_index < utext.Length; text_index++)
{
byte[] encodedBytes = utf8.GetBytes(utext.Substring(text_index, 1));
for (int index = 0; index < encodedBytes.Length; index++)
{
builder.AppendFormat("{0}", Convert.ToString(encodedBytes[index], 16));
}
builder.Append(" ");
}
rchtxtbx_UTF8.SelectionFont = new System.Drawing.Font("San Serif", 20);
rchtxtbx_UTF8.AppendText(builder.ToString() + "\r");
As an example the characters 乘义ש give me e4b998 e4b989 d7a9, note I have a mix LtoR and RtoL text. Now if the user inputs the number e4b998 I want to show them it is 乘, in Unicode 4E58
I have tried a few things and the closest I got, but still far away, is
Encoding utf8 = Encoding.UTF8;
rchtxbx_text.Text = Encoding.ASCII.GetString(utf8.GetBytes(e4b998));
What do I need to do to input e4b998 and write 乘 to a textbox?
Something like this:
Split source into 2-character chunks: "e4b998" -> {"e4", "b9", "98"}
Convert chunks into bytes
Encode bytes into the final string
Implementation:
string source = "e4b998";
string result = Encoding.UTF8.GetString(Enumerable
.Range(0, source.Length / 2)
.Select(i => Convert.ToByte(source.Substring(i * 2, 2), 16))
.ToArray());
If you have an int as source:
string s_unicode2 = System.Text.Encoding.UTF8.GetString(utf8.GetBytes(e4b998));
Hello i need some help modifying this code so it splits this string with hyphens:
string KeyString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
I would like to lay it out like this:
1234-1234-1234-1234
with a char length of 4 per segment and max chars about 16
Full Code
private static string GetKey()
{
char[] chars = new char[62];
string KeyString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
chars = KeyString.ToCharArray();
RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider();
byte[] data = new byte[1];
crypto.GetNonZeroBytes(data);
data = new byte[8];
crypto.GetNonZeroBytes(data);
StringBuilder result = new StringBuilder(8);
foreach (byte b in data)
{
result.Append(chars[b % (chars.Length - 1)]);
}
return result.ToString();
}
the code is used for generating random ids
any help would be appreciated
Can't... resist... regex... solution
string KeyString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
Console.WriteLine(
new System.Text.RegularExpressions.Regex(".{4}")
.Replace(KeyString, "$&-").TrimEnd('-'));
outputs
abcd-efgh-ijkl-mnop-qrst-uvwx-yzAB-CDEF-GHIJ-KLMN-OPQR-STUV-WXYZ-1234-5678-90
But yes, if this is a Guid, by all means, use that type.
How about:
StringBuilder result = new StringBuilder();
for (var i = 0; i < data.Length; i++)
{
if (i > 0 && (i % 4) == 0)
result.Append("-");
result.Append(chars[data[i] % (chars.Length - 1)]);
}
result.Length -= 1; // Remove trailing '-'
It might be worthwhile to have a look into Guid, it produces strings in the format xxxxxxxx-xxxx-xxxx-xxxxxxxx (32 chars) if you definitely want 16 chars, you could take some 16 chars in the middle of the 32 generated by Guid.
Guid guid = Guid.NewGuid(); /* f.e.: 0f8fad5b-d9cb-469f-a165-70867728950e */
string randomid = guid.ToString().Substring(4, 19);