I am running into problems with Hex values and python. I am trying to write a function which performs a bytewise XOR and returns a Hex value.
Basically I am trying to convert this C# code to Python:
private byte[] AddParity(string _in)
{
byte parity = 0x7f;
List<byte> _out = new List<byte>();
ASCIIEncoding asc = new ASCIIEncoding();
byte[] bytes = asc.GetBytes(_in + '\r');
foreach (byte bt in bytes)
{
parity ^= bt;
_out.Add(bt);
}
_out.Add(parity);
return _out.ToArray();
}
Can someone point me in the right direction?
parity = 0x7f
parities = [int(item,16) ^ parity for item in "4e 7f 2b".split()]
#or maybe
parities = [ord(item) ^ parity for item in "somestring"]
I guess you are using this as some sort of checksum
parity = 0x7f
bits = []
for bit in "somestring":
parity ^= ord(bit)
parity &= 0xFF #ensure width
bits.append(bit)
bits.append(parity)
to do the checksum more pythonically you could do
this is the answer you want
bytestring = "vTest\r"
bits = chr(0x7f) + bytestring
checksum = reduce(lambda x,y:chr((ord(x)^ord(y))&0xff),bits)
message = bytestring+checksum
print map(lambda x:hex(ord(x)),message)
#Result:['0x76', '0x54', '0x65', '0x73', '0x74', '0xd', '0x32']
# ser.write(message)
if you want to see the hex values
print map(hex,parities)
or to see the binary
print map(bin,parities)
Related
I want to create byte array that contains 64 bits, How can i get particular bits values say 17th bit, and also how can i get hex value of that index of byte? I did like this, Is this correct?
byte[] _byte = new byte[8];
var bit17=((((_byte[2]>>1)& 0x01);
string hex=BitConverter.ToString(_byte,2,4).Replace("-", string.Empty)
You could use a BitArray:
var bits = new BitArray(64);
bool bit17 = bits[17];
I'm not sure what you mean by the "hex value of that bit" - it will be 0 or 1, because it's a bit.
If you have the index of a bit in a byte (between 0 and 7 inclusive) then you can convert that to a hex string as follows:
int bitNumber = 7; // For example.
byte value = (byte)(1 << bitNumber);
string hex = value.ToString("x");
Console.WriteLine(hex);
You can just use ToString() method.
byte[] arr= new byte[8];
int index = 0;
string hexValue = arr[index].ToString("X");
I'm receiving data using serial port, and I'm use the following code to convert the string to hex representation and show it in the richtextbox5:
string hex = "";
foreach (char c in RXstring)
{
uint tmp = c;
hex += String.Format("{0:X2}", (uint)System.Convert.ToInt16(tmp.ToString())) ;
}
richTextBox5.AppendText(hex + " <= Hex");
where RXstring is where I store data from serial port.
The problem is :
when I send data like 127(decimal)=> 01111111(binary)=> 7F(hex) it converted correctly, while when I send data like 191 or 167 which all share that the most significant bit is 1 and they are all 8 bits the output is 3F despite the other bits, (the representation of any 8 bits start with 1 is 3F), whats wrong with my code?
can you help, thx.
This is an example of using bytes - and it seems to work as you want:
string hex = "";
byte[] RXstring = { 0xFF, 0xCF, 0xB8, 167,191 };
foreach (byte c in RXstring)
{
uint tmp = c;
hex += String.Format("{0:X2}", (uint)System.Convert.ToInt16(tmp.ToString()));
}
System.Console.WriteLine("{0} <= Hex", hex);
I just add serialPort1.Encoding = Encoding.Default; to my serial port and worked perfectly
I have a string and want to convert it to a byte array of hex value using C#.
for eg, "Hello World!" to byte[] val=new byte[] {0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21};,
I see the following code in Converting string value to hex decimal
string input = "Hello World!";
char[] values = input.ToCharArray();
foreach (char letter in values)
{
// Get the integral value of the character.
int value = Convert.ToInt32(letter);
// Convert the decimal value to a hexadecimal value in string form.
string hexOutput = String.Format("0x{0:X}", value);
Console.WriteLine("Hexadecimal value of {0} is {1}", letter, hexOutput);
}
I want this value into byte array but can't write like this
byte[] yy = new byte[values.Length];
yy[i] = Convert.ToByte(Convert.ToInt32(hexOutput));
I try this code referenced from How to convert a String to a Hex Byte Array? where I passed the hex value 48656C6C6F20576F726C6421 but I got the decimal value not hex.
public 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;
}
and I also try code from How can I convert a hex string to a byte array?
But once I used Convert.ToByte or byte.Parse , the value change to decimal value.
How should I do?
Thanks in advance
I want to send 0x80 (i.e, 128) to serial port but when I copy and paste the character equivalent to 128 to the variable 'input' and convert to byte, I got 63 (0x3F). So I think I need to send hex array. I think I got the wrong idea. Pls see screen shot.
For now, I solve this to combine byte arrays.
string input = "Hello World!";
byte[] header = new byte[] { 2, 48, 128 };
byte[] body = Encoding.ASCII.GetBytes(input);
Hexadecimal has nothing to do with this, your desired result is nothing more nor less than an array of bytes containing the ASCII codes.
Try Encoding.ASCII.GetBytes(s)
There's something strange with your requirement:
I have a string and want to convert it to a byte array of hex value
using C#.
An byte is just an 8-bit value. You can present it as decimal (e.g. 16) or hexidecimal (e.g. 0x10).
So, what do you realy want?
In case you are really wanting to get a string which contains the hex representation of an array of bytes, here's how you can do that:
public static string BytesAsString(byte[] bytes)
{
string hex = BitConverter.ToString(bytes); // This puts "-" between each value.
return hex.Replace("-",""); // So we remove "-" here.
}
It seems like you’re mixing converting to array and displaying array data.
When you have array of bytes it’s just array of bytes and you can represent it in any possible way binary, decimal, hexadecimal, octal, whatever… but that is only valid if you want to visually represent these.
Here is a code that manually converts string to byte array and then to array of strings in hex format.
string s1 = "Stack Overflow :)";
byte[] bytes = new byte[s1.Length];
for (int i = 0; i < s1.Length; i++)
{
bytes[i] = Convert.ToByte(s1[i]);
}
List<string> hexStrings = new List<string>();
foreach (byte b in bytes)
{
hexStrings.Add(Convert.ToInt32(b).ToString("X"));
}
I need to convert a string to 7-bit ASCII with even parity in a C# application which communicates with a mainframe. I tried using Encoding.ASCII, however, it does not have the correct parity.
Perhaps something like this:
public static byte[] StringTo7bitAsciiEvenParity(string text)
{
byte[] bytes = Encoding.ASCII.GetBytes(text);
for(int i = 0; i < bytes.Length; i++)
{
if(((((bytes[i] * 0x0101010101010101UL) & 0x8040201008040201UL) % 0x1FF) & 1) == 0)
{
bytes[i] &= 0x7F;
}
else
{
bytes[i] |= 0x80;
}
}
return bytes;
}
Completely untested. Don't ask me how the magic to compute parity works. I just found it here. But some variant of this should do what you want.
I tried to make this work for the case ',' becoming 0x82. But I can't work out how that is supposed to be done. ',' is, in ASCII, binary 00101100 and 0x82 is binary 10000010. I don't see the correlation at all.
You will have to calculate the parity bit yourself. So:
convert string into byte array using built in 8bit ASCII encoding. Most top bit should allways be 0 using this encoding.
do the bit modifications on each byte and set parity bit for each byte.
There is no built-in functionality for calculating parity bit, that I know of.
Assuming byte-level parity and no-endian related behavior (i.e. a stream of bytes), the following works as intended (tested against a known 7-bit ASCII even parity table):
public static byte[] GetAsciiBytesEvenParity(this string text)
{
byte[] bytes = Encoding.ASCII.GetBytes(text);
for(int ii = 0; ii < bytes.Length; ii++)
{
// parity test adapted from:
// http://graphics.stanford.edu/~seander/bithacks.html#ParityParallel
if (((0x6996 >> ((bytes[ii] ^ (bytes[ii] >> 4)) & 0xf)) & 1) != 0)
{
bytes[ii] |= 0x80;
}
}
return bytes;
}
In C I would do this
int number = 3510;
char upper = number >> 8;
char lower = number && 8;
SendByte(upper);
SendByte(lower);
Where upper and lower would both = 54
In C# I am doing this:
int number = Convert.ToInt16("3510");
byte upper = byte(number >> 8);
byte lower = byte(number & 8);
char upperc = Convert.ToChar(upper);
char lowerc = Convert.ToChar(lower);
data = "GETDM" + upperc + lowerc;
comport.Write(data);
However in the debugger number = 3510, upper = 13 and lower = 0
this makes no sense, if I change the code to >> 6 upper = 54 which is absolutely strange.
Basically I just want to get the upper and lower byte from the 16 bit number, and send it out the com port after "GETDM"
How can I do this? It is so simple in C, but in C# I am completely stumped.
Your masking is incorrect - you should be masking against 255 (0xff) instead of 8. Shifting works in terms of "bits to shift by" whereas bitwise and/or work against the value to mask against... so if you want to only keep the bottom 8 bits, you need a mask which just has the bottom 8 bits set - i.e. 255.
Note that if you're trying to split a number into two bytes, it should really be a short or ushort to start with, not an int (which has four bytes).
ushort number = Convert.ToUInt16("3510");
byte upper = (byte) (number >> 8);
byte lower = (byte) (number & 0xff);
Note that I've used ushort here instead of byte as bitwise arithmetic is easier to think about when you don't need to worry about sign extension. It wouldn't actually matter in this case due to the way the narrowing conversion to byte works, but it's the kind of thing you should be thinking about.
You probably want to and it with 0x00FF
byte lower = Convert.ToByte(number & 0x00FF);
Full example:
ushort number = Convert.ToUInt16("3510");
byte upper = Convert.ToByte(number >> 8);
byte lower = Convert.ToByte(number & 0x00FF);
char upperc = Convert.ToChar(upper);
char lowerc = Convert.ToChar(lower);
data = "GETDM" + upperc + lowerc;
Even if the accepted answer fits the question, I consider it incomplete due to the simple fact that the question contains int and not short in header and it is misleading in search results, and as we know Int32 in C# has 32 bits and thus 4 bytes. I will post here an example that will be useful in the case of Int32 use. In the case of an Int32 we have:
LowWordLowByte
LowWordHighByte
HighWordLowByte
HighWordHighByte.
And as such, I have created the following method for converting the Int32 value into a little endian Hex string, in which every byte is separated from the others by a Whitespace. This is useful when you transmit data and want the receiver to do the processing faster, he can just Split(" ") and get the bytes represented as standalone hex strings.
public static String IntToLittleEndianWhitespacedHexString(int pValue, uint pSize)
{
String result = String.Empty;
pSize = pSize < 4 ? pSize : 4;
byte tmpByte = 0x00;
for (int i = 0; i < pSize; i++)
{
tmpByte = (byte)((pValue >> i * 8) & 0xFF);
result += tmpByte.ToString("X2") + " ";
}
return result.TrimEnd(' ');
}
Usage:
String value1 = ByteArrayUtils.IntToLittleEndianWhitespacedHexString(0x927C, 4);
String value2 = ByteArrayUtils.IntToLittleEndianWhitespacedHexString(0x3FFFF, 4);
String value3 = ByteArrayUtils.IntToLittleEndianWhitespacedHexString(0x927C, 2);
String value4 = ByteArrayUtils.IntToLittleEndianWhitespacedHexString(0x3FFFF, 1);
The result is:
7C 92 00 00
FF FF 03 00
7C 92
FF.
If it is hard to understand the method which I created, then the following might be a more comprehensible one:
public static String IntToLittleEndianWhitespacedHexString(int pValue)
{
String result = String.Empty;
byte lowWordLowByte = (byte)(pValue & 0xFF);
byte lowWordHighByte = (byte)((pValue >> 8) & 0xFF);
byte highWordLowByte = (byte)((pValue >> 16) & 0xFF);
byte highWordHighByte = (byte)((pValue >> 24) & 0xFF);
result = lowWordLowByte.ToString("X2") + " " +
lowWordHighByte.ToString("X2") + " " +
highWordLowByte.ToString("X2") + " " +
highWordHighByte.ToString("X2");
return result;
}
Remarks:
Of course insteand of uint pSize there can be an enum specifying Byte, Word, DoubleWord
Instead of converting to hex string and creating the little endian string, you can convert to chars and do whatever you want to do.
Hope this will help someone!
Shouldn't it be:
byte lower = (byte) ( number & 0xFF );
To be a little more creative
[System.Runtime.InteropServices.StructLayout( System.Runtime.InteropServices.LayoutKind.Explicit )]
public struct IntToBytes {
[System.Runtime.InteropServices.FieldOffset(0)]
public int Int32;
[System.Runtime.InteropServices.FieldOffset(0)]
public byte First;
[System.Runtime.InteropServices.FieldOffset(1)]
public byte Second;
[System.Runtime.InteropServices.FieldOffset(2)]
public byte Third;
[System.Runtime.InteropServices.FieldOffset(3)]
public byte Fourth;
}