C# Ascii to bytes, parsing not conversion - c#

I have a windows form where you can input text in one textbox, and it outputs the conversion in the other textbox. I have various conversions.
say I input "hello world"
my ascii to bytes function gives me back: 10410110810811132119111114108100
all is good. now I need to use my bytes to ascii function to convert it back.
the problem is that
byte[] b;
b = ASCIIEncoding.ASCII.GetBytes(plaintext); //it is a string from the textbox
OK, MOSTLY SOLVED, BUT, the problem still remains, input "1101000 1100101" as a string, parse as bytes/ byte array, and then get a string out of it. (I know the last part)

UPDATE
From binary input string to ASCII string
using System;
using System.Linq;
public class Program
{
public static void Main()
{
string input = "1101000 1100101 1101100 1101100 1101111 100000 1110111 1101111 1110010 1101100 1100100";
string[] binary = input.Split(' ');
Console.WriteLine(String.Join("", binary.Select(b => Convert.ToChar(Convert.ToByte(b, 2))).ToArray()));
}
}
Results:
hello world
Demo
OLD ANSWER
So now it sounds like you want to convert your string to binary and then from binary back to a string. From my OLD ANSWER, you can use the Select() (LINQ) statement to convert your string to a binary string array.
Once you have a binary string array, to convert it back you have to convert each element to a byte from base 2, then convert the byte to a char resulting in a char[], from which can be converting back to a string. No padding is necessary.
using System;
using System.Linq;
using System.Text;
public class Program
{
public static void Main()
{
string input = "hello world";
byte[] inputBytes = ASCIIEncoding.ASCII.GetBytes(input);
// Decimal display
Console.WriteLine(String.Join(" ", inputBytes));
// Hex display
Console.WriteLine(String.Join(" ", inputBytes.Select(ib => ib.ToString("X2"))));
// Binary display
string[] binary = inputBytes.Select(ib => Convert.ToString(ib, 2)).ToArray();
Console.WriteLine(String.Join(" ", binary));
// Converting bytes back to string
Console.WriteLine(ASCIIEncoding.ASCII.GetString(inputBytes, 0, inputBytes.Length));
// Binary to ASCII (This is what you're looking for)
Console.WriteLine(String.Join("", binary.Select(b => Convert.ToChar(Convert.ToByte(b, 2)))));
}
}
Results:
104 101 108 108 111 32 119 111 114 108 100
68 65 6C 6C 6F 20 77 6F 72 6C 64
1101000 1100101 1101100 1101100 1101111 100000 1110111 1101111 1110010 1101100 1100100
hello world
hello world
Demo

The inverse to ASCIIEncoding.ASCII.GetBytes(string) is ASCIIEncoding.ASCII.GetString(bytes[]):
string plaintext = "hello world";
byte[] b = ASCIIEncoding.ASCII.GetBytes(plaintext);
Console.WriteLine(b); // new bytes[] { 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100 }
string s = ASCIIEncoding.ASCII.GetString(b);
Console.WriteLine(s); // "hello world"
how the heck does ASCIIEncoding.ASCII.GetBytes("hello world") give me back 10410110810811132119111114108100?! that's not binary!
It does not give you that number. It gives you a byte array; an array of bytes. And a byte is a number between 0 and 255 (which can be stored in one byte, hence them name). What did you expect? A string containing only 1 and 0 characters? That’s not binary either; that’s a string.
You can use Convert.ToString to get a binary string from a single byte:
Console.WriteLine(Convert.ToString(104, 2)); // "1101000"
Note that you need to left-pad those strings to make them use 8 characters.

Related

EBCDIC COMP value to integer

How can I convert an EBCDIC encoded file with PIC S9(04) COMP. to an integer value?
This file contains 1234 in the first line and -1234 on the second line.
Binary:
0101100011010010101100000101000011101111011000001011000001010000
Example:
How can I convert an EBCDIC encoded file with PIC S9(04) COMP. to an integer value?
Don't do that.
During file conversion, the binary data is converted using an EBCDIC to ASCII table. The 04 D2 (+1234) was converted to 1A 4B. The 04 (EBCDIC SEL) was changed to 1A (ASCII SUB), because there is no equivalent for the conversion. The D2 (EBCDIC 'K') was changed to 4B (ASCII 'K'). There is no way to reverse the conversion, due to the SUB. The same problem exists with the conversion of -1234.
Your best bet is to use PIC +9(04), which will be +1234 or -1234 both before and after conversion.
Test data using PIC +9(04) written to file
+1234
-1234
+0001
-0001
+0000
Test program
using System;
using System.IO;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string path = "z:e1.txt";
using (StreamReader sr = new StreamReader(path))
{
while (sr.Peek() >= 0)
{
String s = sr.ReadLine();
short n = Int16.Parse(s);
Console.WriteLine(n);
}
}
}
}
}
Displayed result
1234
-1234
1
-1
0
COBOL data types with computational usage (COMP, COMP-n) are not text, so you must not do any character conversion operation with them.
Computational types are stored as either binary numbers, floating point numbers, or packed decimal numbers. COMP is binary. The length depends on the number of 9s in the PIC clause. Note that the binary types are storeed in big-endian format.
In your case, the PIC +9(4) occupies two bytes, each. For example. if you see
0x1234
as the hexadecimal represetation of a PIC +9(4) COMP field in the input data, this is representing the number (0x12 * 0x100) + 0x34, in decimal (18 * 256) + 52 = 4608 + 52 = 4660.
In summary, mixed data (records) containing fields of types PIC ... USAGE DISPLAY and PIC ... USAGE COMP-n must never be translated, but must be split into indidual fields, and each field must be handled according to its USAGE type.

How to convert From Hex To Dump in C#

I convert my Hex to dump to get special character like symbol but when I try to convert my "0x18" i "\u0018" this value. Can anyone give me solution regarding this matter.
Here is my code:
public static string FromHexDump(string sText)
{
Int32 lIdx;
string prValue ="" ;
for (lIdx = 1; lIdx < sText.Length; lIdx += 2)
{
string prString = "0x" + Mid(sText, lIdx, 2);
string prUniCode = Convert.ToChar(Convert.ToInt64(prString,16)).ToString();
prValue = prValue + prUniCode;
}
return prValue;
}
I used VB language. I have a database that already encrypted text to my password and the value is BAA37D40186D like this so I loop it by step 2 and it will like this 0xBA,0xA3,0x7D,0x40,0x18,0x6D and the VB result getting like this º£}#m
You can use this code:
var myHex = '\x0633';
var formattedString += string.Format(#"\x{0:x4}", (int)myHex);
Or you can use this code from MSDN (https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/how-to-convert-between-hexadecimal-strings-and-numeric-types):
string hexValues = "48 65 6C 6C 6F 20 57 6F 72 6C 64 21";
string[] hexValuesSplit = hexValues.Split(' ');
foreach (string hex in hexValuesSplit)
{
// Convert the number expressed in base-16 to an integer.
int value = Convert.ToInt32(hex, 16);
// Get the character corresponding to the integral value.
string stringValue = Char.ConvertFromUtf32(value);
char charValue = (char)value;
Console.WriteLine("hexadecimal value = {0}, int value = {1}, char value = {2} or {3}",
hex, value, stringValue, charValue);
}
The question is unclear - what is the database column's type? Does it contain 6 bytes, or 12 characters with the hex encoding of the bytes? In any case, this has nothing to do with special characters or encodings.
First, 0x18 is the byte value of the Cancel Character in the Latin 1 codepage, not the pound sign. That's 0xA3. It seems that the byte values in the question are just the Latin 1 bytes for the string in hex.
.NET strings are Unicode (UTF16LE specifically). There's no UTF8 string or Latin1 string. Encodings and codepages apply when converting bytes to strings or vice versa. This is done using the Encoding class and eg Encoding.GetBytes
In this case, this code will convert the byte to the expected string form, including the unprintable character :
new byte[] {0xBA,0xA3,0x7D,0x40,0x18,0x6D};
var latinEncoding=Encoding.GetEncoding(1252);
var result=latinEncoding.GetString(dbBytes);
The result is :
º£}#m
With the Cancel character between # and m.
If the database column contains the byte values as strings :
it takes double the required space and
the hex values have to be converted back to bytes before converting to strings
The x format is used to convert numbers or bytes to their hex form and vice versa. For each byte value, ToString("x") returns the hex string.
The hex string can be produced from the original buffer with :
var dbBytes=new byte[] {0xBA,0xA3,0x7D,0x40,0x18,0x6D};
var hexString=String.Join("",dbBytes.Select(c=>c.ToString("x")));
There are many questions that show how to parse a byte string into a byte array. I'll just steal Jared Parson's LINQ answer :
public static byte[] StringToByteArray(string hex) {
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
With that, we can parse the hex string into a byte array and convert it to the original string :
var bytes=StringToByteArray(hexString);
var latinEncoding=Encoding.GetEncoding(1252);
var result=latinEncoding.GetString(bytes);
First of all u don't need dump but Unicode, I would recomend to read about unicode/encoding etc and why this is a problem with strings.
PS: solution : StackOverflow

C# Convert Hex String Array to Byte Array

I have a String[] of hex values "10" "0F" "3E" "42" stored.
I found this method to convert to a Byte[]
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;
}
However this converts the values to the hex equivalent. But the values are already in the hex equivalent!
For example this makes "10" "0F" "3E" "42" into "16" "15" "62" "66".
I want it to directly copy the values as they are already the correct hex value.
Edit:
Basically...
I want a byte array with the literal characters in the String[] So say the second value in String[] is 0F. I want the first byte in Byte[] to be 0F and not 16
Any ideas?
Edit2
Let me clarify. I don't want to convert my String[] values into Hexadecimal, as they are already Hexadecimal. I want to directly copy them to a Byte[]
The problem is my string of values "10" "0F" "3E" 42" already has the hexadecimal value I want. I want the byte array to contain those exact values and not convert them, they are already hexadecimal form.
You have to convert (or parse) string in order to get byte since string and byte are different types:
// 10 == 10d
byte b = Convert.ToByte("10"); // if "10" is a decimal representation
// 16 == 0x10
byte b = Convert.ToByte("10", 16); // if "10" is a hexadecimal representation
If you want to process an array, you can try a simple Linq:
using System.Linq;
...
string[] hexValues = new string[] {
"10", "0F", "3E", "42"};
byte[] result = hexValues
.Select(value => Convert.ToByte(value, 16))
.ToArray();
If you want to print out result as hexadecimal, use formatting ("X2" format string - at least 2 hexadecimal digits, use captital letters):
// 10, 0F, 3E, 42
Console.Write(string.Join(", ", result.Select(b => b.ToString("X2"))));
Compare with same array but in a different format ("d2" - at least 2 decimal digits)
// 16, 15, 62, 66
Console.Write(string.Join(", ", result.Select(b => b.ToString("d2"))));
If no format provided, .Net uses default one and represents byte in decimal:
// 16, 15, 62, 66
Console.Write(string.Join(", ", result));
You're really confusing representation and numbers here.
A string like "0F" can be seen as a representation of a number in base 16, that is, in decimal representation, 16.
Which is the exact same thing as representing 16 as F or 0F or XVI or
IIIIIIIIIIIIIIII or whatever other representation you choose.
The string "0F" actually looks in memory like this
Hexadecimal representation:
0x30 0x46 0x00
Decimal representation:
48 70 0
Binary representation:
0b00110000 0b01000110 0b00000000
Byte is simply a data type which is infact a subset of an integer.
Byte takes interger values ranging from -2^7(-128) to 2^7-1$(127)
Calling Convert.ToByte(string, 16) simply converts your string to an equivalent hex value and then to an equivalent value in byte.
Note the byte data type is always an integer data but used in place of an integer just to save space in memory. As referenced above the byte datatype takes values from -128 to 127 thereby saving you more space in memory than the integer data type would.
Please Note that you are likely to run into an error if the hexadecimal value you wish to convert to byte is less than -128 or greater than 127
The link below shows an instance of this error when I try converting a string whose value when converted to hexadecimal is greater than 127.
Error when converting to Byte
You get an error whenever you do this.
I hope my answer and Dmitry Bychenko's sheds more light into your problem.
Please feel free to comment if it doesnt.

Convert from Hexadecimal to Text

With respect to this tool, I need to convert hexadecimal data, irrespective of their combination to equivalent text. For example:
"HelloWorld" = 48656c6c6f576f726c64;
The solution needs to take into account that hexadecimal can be grouped in different lengths:
48656c6c 6f576f72 6c64
or
48 65 6c 6c 6f 57 6f 72 6c 64
All of the hexadecimal values supplied above read as HelloWorld when converted to text.
First, I would like to point out that this question has been asked many times on the web (here is one example). However, I am going to break this down step by step for you to hopefully teach you how to not only utilize your resources available on the web, but also how to solve your problem.
Overview: Converting from hexadecimal data to text that is able to be read by human beings is a straight-forward process in modern development languages; you clean the data (ensuring no illegal characters remain), then you convert down to the byte level so that you can work with the raw data. Finally, you'll convert that raw data into readable text utilizing a method that has already been created by Microsoft.
Important: Remember, for the conversion to work, you have to ensure you're converting in the same format that you started with:
ASCII -> ASCII: Works Great!
ASCII -> UTF7: Not so much...
Removing Illegal Characters: One of the first things you'll need to do is ensure the hexadecimal value that you're supplying doesn't contain any illegal characters. The simplest way to do this is to create an array of acceptable characters and then remove anything but these in a loop:
private string GetCleanHex(string hex) {
string legalCharacters = "0123456789ABCDEF";
string result = hex.ToUpper();
foreach (char c in result) {
if (!legalCharacters.Contains(c))
result = result.Replace(c.ToString(), string.Empty);
}
}
Getting The Byte Array: Once you've cleaned out all illegal characters, you can now convert your hexadecimal string into a byte array. This is required to convert from hexadecimal to ASCII. This step was provided by the linked post above:
private byte[] GetBytesFromHex(string hex) {
byte[] bytes = new byte[result.Length / 2];
for (int i = 0; i < bytes.Length; i++)
bytes[i] = Convert.ToByte(result.Substring(i * 2, 2), 16);
}
Converting To Text: Now that you've cleaned your data, and converted it to a byte[], you can now convert that byte data into ASCII. This can be done using a method available in Encoding.ASCII called GetString:
string text = Encoding.ASCII.GetString(bytes);
The Final Result: Plug all of this into your application and you'll have successfully converted hexadecimal data into clean, readable text:
string hex = GetCleanHex("506c 65 61736520 72 656164 20686f77 2074 6f 2061 73 6b 2e");
byte[] bytes = GetBytesFromHex(hex);
string text = Encoding.ASCII.GetString(bytes);
Console.WriteLine(text);
Console.ReadKey();
The code above will print the following text to the console:
Please read how to ask.

Why are ASCII values of a byte different when cast as Int32?

I'm in the process of creating a program that will scrub extended ASCII characters from text documents. I'm trying to understand how C# is interpreting the different character sets and codes, and am noticing some oddities.
Consider:
namespace ASCIITest
{
class Program
{
static void Main(string[] args)
{
string value = "Slide™1½”C4®";
byte[] asciiValue = Encoding.ASCII.GetBytes(value); // byte array
char[] array = value.ToCharArray(); // char array
Console.WriteLine("CHAR\tBYTE\tINT32");
for (int i = 0; i < array.Length; i++)
{
char letter = array[i];
byte byteValue = asciiValue[i];
Int32 int32Value = array[i];
//
Console.WriteLine("{0}\t{1}\t{2}", letter, byteValue, int32Value);
}
Console.ReadLine();
}
}
}
Output from program
CHAR BYTE INT32
S 83 83
l 108 108
i 105 105
d 100 100
e 101 101
T 63 8482 <- trademark symbol
1 49 49
½ 63 189 <- fraction
" 63 8221 <- smartquotes
C 67 67
4 52 52
r 63 174 <- registered trademark symbol
In particular, I'm trying to understand why the extended ASCII characters (the ones with my notes added to the right of the third column) show up with the correct value when cast as int32, but all show up as 63 when cast as the byte value. What's going on here?
ASCII.GetBytes conversion replaces all characters outside of ASCII range (0-127) with question mark (code 63).
So since your string contains characters outside of that range your asciiValue have ? instead of all interesting symbols like ™ - its Char (Unicode) repesentation is 8482 which is indeed outside of 0-127 range.
Converting string to char array does not modify values of characters and you still have original Unicode codes (char is essentially Int16) - casting it to longer integer type Int32 does not change the value.
Below are possible conversion of that character into byte/integers:
var value = "™";
var ascii = Encoding.ASCII.GetBytes(value)[0]; // 63(`?`) - outside 0-127 range
var castToByte = (byte)(value[0]); // 34 = 8482 % 256
var Int16 = (Int16)value[0]; // 8482
var Int32 = (Int16)value[0]; // 8482
Details available at ASCIIEncoding Class
ASCIIEncoding corresponds to the Windows code page 20127. Because ASCII is a 7-bit encoding, ASCII characters are limited to the lowest 128 Unicode characters, from U+0000 to U+007F. If you use the default encoder returned by the Encoding.ASCII property or the ASCIIEncoding constructor, characters outside that range are replaced with a question mark (?) before the encoding operation is performed.

Categories

Resources