Converting from a mainframe packed decimal number to an integer in C# - c#

I've spent the better part of a week and finally figured out how to convert packed data from the mainframe into a hexadecimal number representation. Now, I am trying to figure out how to get that hexadecimal string into an integer in Visual C#. I'm sure there's an easy function for this, but it's bypassing my searches at the moment. Here's the code that is giving me the mainframe representation:
// Get the packed decimal field from the input record
String testString = dataRecord.Substring(40, 4);
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
Byte[] bytes = encoding.GetBytes(testString);
// Create two different encodings.
Encoding ascii = Encoding.ASCII;
Encoding ebcdic = Encoding.GetEncoding("IBM037");
// Unpack Data
Byte[] bt = Encoding.Convert(ascii, ebcdic, bytes);
// Get the data into a string in the format of 00-5F (represents a positive 5)
// The format of 00-5D (represents a negative 5)
String numberString = BitConverter.ToString(bt);
If the mainframe decimal value is 5, bt[0] ends up being 00, and bt[1] ends up being 5F. After converting to a string, I end up with "00-5F". What I really want to have, is an integer or string that just says "5". I could just write my own thing to test every digit, and return the correct value, but I'm thinking there has to be a way to convert from a hexidecimal signed number to a string or integer without having to write a routine of my own. Does anyone have any ideas what the function might be? I've tried the standard convert.toint, todecimal, etc. functions but they get freaked out by this format.
Thanks!

Related

Is there a different way to convert to hexadecimal?

I'm trying to write some information to a special device that requires me to encode the string and I quote " an even number of bytes to write (1-32, base 10) "
The example string provided "DE AD BE EF CA FE" (works).
I have converted my string to decimal and from decimal to hexadecimal.
string TextToConvert = "Test Andrei";
TextToConvert=ConvertStringToHex(TextToConvert, Encoding.UTF8);
List<char> Chars = TextToConvert.ToCharArray().ToList();
string CharValue = "";
string secondHexConvert = "";
foreach(char c in Chars)
{
CharValue+=Convert.ToInt32(c);
secondHexConvert+=Convert.ToString(c, 16)+" ";
}
string hexValue = String.Format("{0:X}", CharValue)+" ";
I have found on internet a tool that converts to hexadecimal that works. The problem is that I can't figure what type of encoding is that. The site is this: https://codebeautify.org/decimal-hex-converter
from decimal "841011151163265110100114101105" to hex = "a9d741e82c990000000000000"
To convert such a big integer to a hexadecimal string, use the aptly named BigInteger type:
var num = BigInteger.Parse("841011151163265110100114101105");
string hex = num.ToString("X");
Console.WriteLine(hex);
will output:
0A9D741E82C98FC6A137B75371
but here's a snag, the output you showed in your question is somewhat different, let me show it together with what the code above produces:
0A9D741E82C98FC6A137B75371
a9d741e82c990000000000000
As you can see, the numbers start the same but your example then ends up with lots of zeroes.
The only way I understand this could happen is that they're in fact not using a type that can hold that many significant digits, so you get a rounding error.
Many of the dynamic programming languages allows you to use floating point numbers and integers interchangeably, I guess this is what happened, a floating point type that can only hold 17-18 significant digits or some such was used, and you lost precision. .NET, however, doesn't have built-in support for converting floating point types to hexadecimal.
You can see that .NET produces the exact value by converting back:
Console.WriteLine(BigInteger.Parse(hex, System.Globalization.NumberStyles.HexNumber));
outputs:
841011151163265110100114101105
In other words, I'm not sure you can get the exact same results in .NET.
Corollary: Don't use that site for this kind of conversion!
You can use the following code to convert a string to hexadecimal:
public static string ConvertStringToHex(String input, System.Text.Encoding encoding)
{
Byte[] stringBytes = encoding.GetBytes(input);
StringBuilder sbBytes = new StringBuilder(stringBytes.Length * 2);
foreach (byte b in stringBytes)
{
sbBytes.AppendFormat("{0:X2}", b);
}
return sbBytes.ToString();
}
And you just call it using:
string testString = "11111111";
string hex = ConvertStringToHex(testString, System.Text.Encoding.Unicode);

Converting hex to decimal

I have an array of strings that are in hex format, for example {"3d", "20", "5a"}.
What would be a good way of converting each element of this string to decimal format?
I've tried using GetBytes(), but that doesn't seem to work since it sees "3d" as two different characters because it doesn't know that it is in hex format.
GetBytes() works fine in a situation like below but not if characters are in hex.
What am I missing here?
string a = "T";
byte[] b = {10};
b = System.Text.UTF8Encoding.Default.GetBytes(a);
Use int.Parse with NumberStyles.HexNumber.
int decValue = int.Parse(hexValue,System.Globalization.NumberStyles.HexNumber);
Try that.
HexValue is the number in hex format and decValue is in decimal...

conversion to byte gives this error : Input string was not in a correct format

i am using convert.tobyte to convert string to byte. the problem is if the data is:
string data = "5";
byte b = Convert.tobyte(data); works fine.
but, if
string data = "S"
byte b = Convert.tobyte(data); DOESN'T WORK!
ERROR : Input string was not in a correct format
What is wrong and how to solve it?
Note: i am extracting a values from textbox, so the conversion works only if the input is number digits, not characters.
how to include the characters?
Thanks.
This is exactly how Convert.ToByte method works http://msdn.microsoft.com/en-us/library/y57wwkzk.aspx
Only digits in string accepted.
Did you meant converting the string to byte array? If so, use:
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(yourString);
For strings containing only ASCII characters, the size of array will be equal to length of your string and every byte in array will be an ord value for the character. If string contains multibyte characters the size of array will be greater than length of string.
When you are not sure if a variable of string type could be correctly converted to a number you need to use the TryParse family of methods like Byte.TryParse method
string data = "S";
byte b;
if(byte.TryParse(data, out b))
Console.Writeline("Worked: " + b.ToString());
The TryParse has the advantage to not throw an exception if the string cannot be converted to a number and return just false or true while the out parameter is filled with the converted value if possible.

Hashing text with SHA-256 at Windows Forms

String inputPass = textBox2.Text;
byte[] inputBytes = System.Text.Encoding.UTF8.GetBytes(inputPass);
byte[] inputHashedBytes = Sha256.ComputeHash(inputBytes);
String inputHash = Convert.ToBase64String(inputHashedBytes);
I'm getting some strange output:
Q9nXCEhAn7RkIOVgBbBeOd5LiH7FWFtDFJ22TMLSoH8=
By output hash looks like this:
43d9d70828409fb46420e56005b05e38de4b887ec5585b43149db64cc2d2a07f
// This is where you get the actual binary hash
byte[] inputHashedBytes = Sha256.ComputeHash(inputBytes);
// But you want it in a string format, similar to a variety of Unix tools
string result = BitConverter.ToString(inputHashedBytes)
// This will remove all the dashes in between each two characters
.Replace("-", string.Empty)
// And make it lowercase
.ToLower();
Encoding.UTF8.GetString parses bytes as UTF-8 code points.
The SHA-256 hash is an arbitrary 256-bit number and does not correspond to any Unicode text.
You probably want to show the binary value in hexadecimal, by calling BitConverter.ToString(). You can also call Convert.ToBase64String().

How can I find the starting index of a string within a UTF-8 byte array? (C#)

I have a UTF-8 byte array of data. I would like to search for a specific string in the array of bytes in C#.
byte[] dataArray = (some UTF-8 byte array of data);
string searchString = "Hello";
How do I find the first occurrence of the word "Hello" in the array dataArray and return an index location where the string begins (where the 'H' from 'Hello' would be located in dataArray)?
Before, I was erroneously using something like:
int helloIndex = Encoding.UTF8.GetString(dataArray).IndexOf("Hello");
Obviously, that code would not be guaranteed to work since I am returning the index of a String, not the index of the UTF-8 byte array. Are there any built-in C# methods or proven, efficient code I can reuse?
Thanks,
Matt
One of the nice features about UTF-8 is that if a sequence of bytes represents a character and that sequence of bytes appears anywhere in valid UTF-8 encoded data then it always represents that character.
Knowing this, you can convert the string you are searching for to a byte array and then use the Boyer-Moore string searching algorithm (or any other string searching algorithm you like) adapted slightly to work on byte arrays instead of strings.
There are a number of answers here that can help you:
byte[] array pattern search
Try the following snippet:
// Setup our little test.
string sourceText = "ʤhello";
byte[] searchBytes = Encoding.UTF8.GetBytes(sourceText);
// Convert the bytes into a string we can search in.
string searchText = Encoding.UTF8.GetString(searchBytes);
int position = searchText.IndexOf("hello");
// Get all text that is before the position we found.
string before = searchText.Substring(0, position);
// The length of the encoded bytes is the actual number of UTF8 bytes
// instead of the position.
int bytesBefore = Encoding.UTF8.GetBytes(before).Length;
// This outputs Position is 1 and before is 2.
Console.WriteLine("Position is {0} and before is {1}", position, bytesBefore);

Categories