How can I improve my hex-based conversion - string

I was facing a problem where I got data (String) from a database with Linebreaks as (Hex) 0D. I displayed this data in a Textbox, which did not use the 0D as a linbreak. I found that the Textbox needs 0D-0A (LF & CR, dont know which is which) to actually show the new line. To solve this problem I came up with the following code.
Private Function convertString(txt As String) As String
Dim data = System.Text.Encoding.Default.GetBytes(txt)
Dim hexString As String = BitConverter.ToString(data)
hexString = hexString.Replace("0D", "0D-0A")
Dim arr As [String]() = hexString.Split("-"c)
Dim array As Byte() = New Byte(arr.Length - 1) {}
For i As Integer = 0 To arr.Length - 1
array(i) = Convert.ToByte(arr(i), 16)
Next
Return System.Text.Encoding.Default.GetString(array)
End Function
Explanation/procedure:
1. Convert String to ByteArray
2. Convert ByteArray to Hex-String (Hex-Chars separated by '-' )
3. Adding the missing lf or cr by replacing the solo one
4. Convert Hex-String back to ByteArray
5. Convert ByteArray back to String
Now my question:
I am pretty sure there is a better way to do that. How can I simplify those lines of code?

You should be able to just Replace vbCr with vbCrLf:
Dim txt = "This is a" & vbCr & "test"
Encoding.UTF8.GetBytes(txt).HexDump()
gives (HexDump is a custom utility method, but not relevant to the question):
00000000 54 68 69 73 20 69 73 20 61 0D 74 65 73 74 This is a·test
Dim txt2 = txt.Replace(vbCr, vbCrLf)
Encoding.UTF8.GetBytes(txt2).HexDump()
gives:
00000000 54 68 69 73 20 69 73 20 61 0D 0A 74 65 73 74 This is a··test
So, your whole method would be:
Private Function convertString(txt As String) As String
Return txt.Replace(vbCr, vbCrLf)
End Function

Related

What is the equivalent of perl's Win32::OLE::Variant in Python 3

I have the following code snippet in perl for automating an application script using Win32::OLE
use Win32::OLE;
use Win32::OLE::Variant;
my $app = new Win32::OLE 'Some.Application';
my $InfoPacket = "78 00 C4 10 95 B4
00 02 31 7F 80 FF";
my #Bytes = split(/[ \n][ \n]*/, $InfoPacket);
my #HexBytes;
foreach(#Bytes)
{
push #HexBytes, eval "0x$_";
}
my $Packet = pack("C12", #HexBytes);
my $VarPacket = Variant(VT_UI1, $Packet);
my $InfoObj = app -> ProcessPacket($VarPacket);
print $InfoObj -> Text();
I have converted the entire code in Python 3, except for the [exact] equivalent of pack() and Variant() functions.
from win32com.client import Dispatch
from struct import pack
app = Dispatch("Some.Application")
InfoPacket = "78 00 C4 10 95 B4 \
00 02 31 7F 80 FF"
Bytes = InfoPacket.split()
HexBytes = [int(b, 16) for b in Bytes]
Packet = pack('B'*12, *HexBytes) # This however, is not giving the exact same output as perl's...
VarPacket = ... # Need to know the python equivalent of above Variant() function...
InfoObj = app.ProcessPacket(VarPacket)
print (InfoObj.Text())
Please suggest the python equivalent of the pack() and Variant() functions used in perl script in the given context so that the final variable VarPacket can be used by Python's Dispatch object to properly generate the InfoObj object.
Thanks !!!
I am not sure about the Python equivalent of the Perl Variant, but for the first question about packing the unsigned char array, the following works for me:
from struct import pack
def gen_list():
info_packet = "78 00 C4 10 95 B4 00 02 31 7F 80 FF"
count = 0
for hex_str in info_packet.split():
yield int(hex_str, 16)
count += 1
for j in range(count, 120):
yield int(0)
packet = pack("120B", *list(gen_list()))
Edit
From the test file testPyComTest.py it looks like you can generate the variant like this:
import win32com.client
import pythoncom
variant = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_UI1, packet)

How to convert to ascii using node.js

I am trying to convert length message to ascii.
My length message is like
var ll = "0170";
In node js , is there some kind of function which converts into ascii?
Please help?
Here's a simple function(ES6) which converts a string into ASCII characters using charCodeAt()
const toAscii = (string) => string.split('').map(char=>char.charCodeAt(0)).join(" ")
console.log(toAscii("Hello, World"))
Output:
-> 72 101 108 108 111 44 32 87 111 114 108 100
You could create a prototype function aswell. There are many solutions :)
you can't have an ascii code for a whole string.
An ascii code is an integer value for a character, not a string. Then for your string "0170" you will get 4 ascii codes
you can display these ascii codes like this
var str = "0170";
for (var i = 0, len = str.length; i < len; i++) {
console.log(str[i].charCodeAt());
}
Ouput : 48 49 55 48
use charCodeAt() function to covert asscii format.
var ll = "0170";
function ascii (a) { return a.charCodeAt(); }
console.log(ascii(ll[0]),ascii(ll[1]), ascii(ll[2]), ascii(ll[3]) )
result:
48 49 55 48

mocha use chai test object equality doesnt work as expected

I'm using "chai" to test a response data of https,the data is like is:
let req = https.request(options, (res) => {
res.on('data', (data) => {
return callback(null, data);
});
});
The test code like this:
let chai = require("chai");
let expect = chai.expect;
console.log("data=" + data);
console.log("typeof data = " + typeof(data));//object
console.log("util.isObject(data) = " + util.isObject(data));//true
console.log("util.isString(data) = " + util.isString(data));//false
// assert.isObject(data, "object");
expect(JSON.stringify(data)).to.be.an("string");//ok
expect(JSON.parse(data)).to.be.an("object");//ok
expect(data).to.be.an("object");//error
Mocha test failed at "expect(data).to.be.an("object");",log like this:
data={"data":{"isDulp":false,"bindTb":false},"req_id":"REQ_APP-1487212987084_2851"}
typeof data = object
util.isObject(data) = true
util.isString(data) = false
Uncaught AssertionError: expected <Buffer 7b 22 64 61 74 61 22 3a 7b 22 69 73 44 75 6c 70 22 3a 66 61 6c 73 65 2c 22 62 69 6e 64 54 62 22 3a 66 61 6c 73 65 7d 2c 22 72 65 71 5f 69 64 22 3a 22 ... > to be an object
I thought 'data' is a object, and when I use typeof to test it, it print "object", but when I use chai "expect(data).to.be.an("object")" the test case failed.
If I use "expect(JSON.parse(data)).to.be.an("object")", the test case passed.
Some one who can tell me why? What the type of the 'data'?
The expected buffer result shows that your endpoint returns a buffer instead of an object, assert String works because it is an string of course. I am guessing that the reason it fails is that data is not an object but a buffer.

Octave advanced textread usage, bash

I have following text file:
079082084072079032084069067072000000000,0
082078032049050032067072065082071069000,1
076065066032065083083084000000000000000,0
082078032049050072082000000000000000000,1
082078032049050072082000000000000000000,1
082078032049050072082000000000000000000,1
070083087032073073032080068000000000000,0
080067065032049050032072082000000000000,0
082078032056072082000000000000000000000,1
070083087032073073073000000000000000000,0
082078032087069069075069078068000000000,1
082078032049050072082000000000000000000,1
077065073078084032077069067072032073073,0
082078032049050072082000000000000000000,1
080067065032049050032072082000000000000,0
082078032049050072082000000000000000000,1
I need too matrices:
X size 16x13
Y size 16x1
I want to separate each row of the file into 13 values, example:
079 082 084 072 079 032 084 069 067 072 000 000 000
Is it possible to import it into octave using textread function?
If no, can it be done using Linux bash command?
Yes, you can do this with textscan (see bottom if you really want to use textread:
octave> txt = "079082084072079032084069067072000000000,0\n082078032049050032067072065082071069000,1";
octave> textscan (txt, repmat ("%3d", 1, 13))
ans =
{
[1,1] =
79
82
[1,2] =
82
78
[1,3] =
84
32
[1,4] =
72
49
[...]
Note that you are reading them as numeric values, so you do not get the preceding zeros. If you want them, you can either read them as string by using "%3s" in the format (extra trouble to handle and reduced performance since you will then be handling cell arrays).
Since you are reading from a file:
[fid, msg] = fopen ("data.txt", "r");
if (fid)
error ("failed to fopen 'data.txt': %s", msg);
endif
data = textscan (fid, repmat ("%3d", 1, 13));
fclose (fid);
If you really want to use textread:
octave> [d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13] = textread ("data.txt", repmat ("%3d", 1, 13))
d1 =
79
82
76
[...]
d2 =
82
78
65
[...]
or:
octave> data = cell (1, 13);
octave> [data{:}] = textread ("data.txt", repmat ("%3d", 1, 13))
data =
{
[1,1] =
79
82
76
[...]
[1,2] =
82
78
65
[...]
If you need to capture the value after the comma (not really part of your original question), you can use:
octave> textscan (txt, [repmat("%3d", 1, 13) ",%1d"])
ans =
{
[1,1] =
79
82
[1,2] =
82
78
[1,3] =
84
32
[...]
[1,14] =
0
1
}
You can do this pretty easily by reading three characters at a time using read in the shell:
while IFS="${IFS}," read -rn3 val tail; do
[[ $tail ]] && echo || printf '%s ' "$val"
done < file
This implementation assumes that if we encounter a value after the comma, we should go to the next line.

Need to convert Image file back to X Y co-ordinate format

I am drawing an signature like this as given below and taking X Y cordinate and saving it to the arry list.
Bitmap bmp;
//Graphics object
Graphics graphics;
//Pen object
Pen pen = new Pen(Color.Black);
// Array List of line segments
ArrayList pVector = new ArrayList();
//Point object
Point lastPoint = new Point(0, 0);
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
// process if currently drawing signature
if (!drawSign)
{
// start collecting points
drawSign = true;
// use current mouse click as the first point
lastPoint.X = e.X;
lastPoint.Y = e.Y;
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
// process if drawing signature
if (drawSign)
{
if (graphics != null)
{
// draw the new segment on the memory bitmap
graphics.DrawLine(pen, lastPoint.X, lastPoint.Y, e.X, e.Y);
pVector.Add(lastPoint.X + " " + lastPoint.Y + " " + e.X + " " + e.Y);
// update the current position
lastPoint.X = e.X;
lastPoint.Y = e.Y;
// display the updated bitmap
Invalidate();
}
}
}
Using the arrylist (pVector) I am saving the values to the database as string(singature ) and aslo as image as given below
//Saving value to Database
ArrayList arrSign = new ArrayList();
arrSign = this.signatureControl.getPVector();
string singature = "";
for (int i = 0; i < arrSign.Count; i++)
{
singature = singature + arrSign[i].ToString() + "*";
}
the string singature wiil be like this
60 46 59 48*59 48 59 51*59 51 59 53*59 53 60 49*60 49 61 44*61 44 62 38*62 38 64 31*64 31 67 23*67 23 70 14*70 14 72 10*72 10 75 3*75 3 77 -2*77 -2 76 2*76 2 75 6*75 6 72 17*72 17 71 24*71 24 69 31*69 31 68 46*68 46 67 59*67 59 68 71*68 71 69 79*69 79 70 86*70 86 71 89*71 89 71 93*71 93 71 95*71 95 71 97*71 97 70 95*70 95 69 88*69 88 68 81*68 81 69 77*69 77 69 68*69 68 71 60
//Saving as Image file
Pen pen = new Pen(Color.Black);
string[] arrStr = (signature.Split('*'));
Graphics graphics;
Bitmap bmp = new Bitmap(300, 200);
graphics = Graphics.FromImage(bmp);
graphics.Clear(Color.White);
for (int i = 0; i < arrStr.Length - 2; i++)
{
string[] strArr = new string[4];
strArr = ((arrStr[i].ToString()).Split(' '));
graphics.DrawLine(pen, Convert.ToInt32(strArr[0].ToString()), Convert.ToInt32(strArr[1].ToString()),
Convert.ToInt32(strArr[2].ToString()), Convert.ToInt32(strArr[3].ToString()));
}
string pathToCopyImage = systemBus.TempFile;
bmp.Save(pathToCopyImage + "\\" + dsReportDetails.Tables["tblDelivery"].Rows[0]["PKDelivery"].ToString() + "_Signature.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
bmp.Dispose();
My problem is that after Saving the signature as Image file I am not able to convert it back to arrylist like the one that i am used to save the value in the database.
ie I need to convert the image file back to as given below format
60 46 59 48*59 48 59 51*59 51 59 53*59 53 60 49*60 49 61 44*61 44 62 38*62 38 64 31*64 31 67 23*67 23 70 14*70 14 72 10*72 10 75 3*75 3 77 -2*77 -2 76 2*76 2 75 6*75 6 72 17*72 17 71 24*71 24 69 31*69 31 68 46*68 46 67 59*67 59 68 71*68 71 69 79*69 79 70 86*70 86 71 89*71 89 71 93*71 93 71 95*71 95 71 97*71 97 70 95*70 95 69 88*69 88 68 81*68 81 69 77*69 77 69 68*69 68 71 60
Will any one help me please
It is not very easy to get your "signature string" back from image so you can just add you "string signature" to saved image as a metadata tag of image (as a Description for example). So then you read your image back you don't need to recognize "signature string" from image, you can just read it from metadata as a string. Msdn has a nice article about image metadata and api to work with them. http://msdn.microsoft.com/en-us/library/ms748873.aspx
By the way, your code for concatenating "signature string" is slow and memory consuming. It is better to use StringBuilder in such situations in .Net. And overall strings are not the best data structure to store list of points. But it depends on requirements for your app.

Resources