How to convert byte array to hex string? - javascript

Here is the sample code in JS :
function toHexString(bytes) {
return bytes.map(function(byte) {
return ("00" + (byte & 0xFF).toString(16)).slice(-2);
}).join('');
}
input -> Buffer.from("333138383223633D77DB", 'hex')
output -> 333138383223630770
Here is what I have tried so far in Python
def toHexString(byteArray):
return ''.join('{:02x}'.format(x) for x in byteArray)
input -> bytearray.fromhex("333138383223633D77DB")
output -> 333138383223633d77db
I think the logic is correct but does not know what is wrong
My expectation result of the Python code should be similar to the result of JS code.
I would like to ask how should I update the python code to get the exact result as JS code

Your Python code is correct (although it can be written much more concise as the other answers suggest), but your JS code isn't because it clearly outputs a hex string that is not the same as the input.
Instead, fix your JS code:
function toHexString(bytes) {
return bytes.toString('hex').toUpperCase();
}
input -> Buffer.from("333138383223633D77DB", 'hex')
output -> 333138383223633D77DB
EDIT: if you really insist on Python code that outputs the same broken hex string, this may work:
import re
input = '333138383223633D77DB';
output = ''
for m in re.finditer(r'..', input):
match = m.group(0)
output += match if re.match('[0-9][0-9]', match) else '0'
print(output)
(my Python skills are extremely rusty so it may not work for all inputs, and/or it can be written much more concise)

with python 3.5+ you can use hex()
def toHexString(byteArray):
return byteArray.hex()
honestly do not think there is any need for defining any helper function when you can just run byteArray.hex()

As has already been stated, there is built-in functionality for this in Python. However, if you insist on re-inventing the wheel then:
hs = '333138383223633D77DB'
def toHexString(ba):
return ''.join([f'{b:02X}' for b in ba])
assert toHexString(bytearray.fromhex(hs)) == hs
Note the use of uppercase 'X' in the format specifier.
Also worth mentioning that bytearray.hex() returns a string in ASCII lowercase

Related

How to accept an input in the console from the user (JS)?

I tried to create a JavaScript program that outputs the binary format of an English letter on input. I had to put the value in the code. How can the value be entered in the console when the program runs?
function returnBinaryLetter(char) {
return ((/^[a-z]$/).test(char)) ? char.charCodeAt(0).toString(2).padStart(8, '0') : 'Sorry, that is not a letter.'
}
// Something like:
// const input = consoleInputFunction('Enter a number.');
// console.log(returnBinaryLetter(input.toLowerCase()));
EDIT 1: This is not for a webpage. This is a JS program which I will run using Node.js. I require a solution with just JS, not with some framework (if that is even possible, mentioning just to be specific).
EDIT 2: I have made the code better after suggestions in Endothermic Dragon's answer.
To directly answer your question, you would use prompt to get a user input in this case.
However, you don't need all of that code. Try this:
function returnBinaryLetter(char) {
if ((/^[a-z]$/).test(char)) {
return char.charCodeAt(0).toString(2).padStart(8, '0')
} else {
return 'Sorry, that is not a letter.'
}
}
var input = prompt('Enter letter to be converted to binary:').toLowerCase();
console.log(returnBinaryLetter(input))
While it may seem a bit intimidating, here's the whole thing broken down:
Ask for an input using prompt, and convert it to lowercase.
Pass the character to the function returnBinaryLetter, and log the output.
Now for the function returnBinaryLetter:
Check if it is a single lowercase letter, using some RegEx.
If it is, return binary. Otherwise, return an error with a description.
Hmm, but how does the binary conversion work?
First, take the character and get its character code.
Next, convert that code to binary.
Finally, pad the start so it is an 8-bit number. If it is not 8 digits, add on 0s at the beginning until it is.
Here, you can see that a more dynamic conversion looks much shorter, and cleaner as well, compared to manually entering about 28 lines of code.
Bonus:
Surprise, surprise! You can further shorten it. Using a ternary operator, you can skip the if-else statement.
function returnBinaryLetter(char) {
return ((/^[a-z]$/).test(char)) ? char.charCodeAt(0).toString(2).padStart(8, '0') : 'Sorry, that is not a letter.'
}
var input = prompt('Enter letter to be converted to binary:').toLowerCase();
console.log(returnBinaryLetter(input))
Now, it's a one-liner!
A ternary operator is usually used within variables when you want to assign its value based on a condition. The ternary operator first checks if the condition inside the brackets is true, and if it is, it returns the first statement (between ? and :), and if not, it returns the second statement (after the :). Pairing this with the return statement of a function, you get a one-liner function!
Feedback:
Since it seems that you are following CamelCase, I thought I would mention that function names should always start with a capital letter, along with each word after that also starting with a capital letter. Variables are different however - for variables, you do make the first letter lowercase, but make all the other words uppercase. In addition, the function name returnBinaryLetter might seem intuitive to you, but not for anyone looking at the code. A more intuitive name that exactly describes its function would be LowercaseLetterToBinary.
For NodeJS, You can use inquirer, which provides different kinds of prompts for the command line (such as text, list, checkbox etc).
Prerequistes:
Install it with npm install inquirer
Example
const { prompt } = require("inquirer");
async main() {
const binaryLetter = await prompt({
type: 'input',
name: 'letter',
message: `What's your name >>`
})
.then(answer => returnBinaryLetter(answer['letter']));
}
main();

How decode HEX in XMLHtppRequest?

I have a site and I used AJAX. And I got some problems.
Server return JSON string something like this {a:"x48\x65\x6C\x6C\x6F"}.
Then in xx.responseText, we have this string '{a:"\x48\x65\x6C\x6C\x6F"}'.
But if I create JavaScript string "\x48\x65\x6C\x6C\x6F" then I have "Hello" and not HEX!
Is it possible get in xx.responseText "real" text from HEX (automatically, without .replace())?
If the output is at all regular (predictable), .replace() is probably the simplest.
var escapeSequences = xx.responseText.replace(/^\{a:/, '').replace(/\}$/, '');
console.log(escapeSequences === "\"\\x48\\x65\\x6C\\x6C\\x6F\""); // true
Or, if a string literal that's equivalent in value but may not otherwise be the same is sufficient, you could parse (see below) and then stringify() an individual property.
console.log(JSON.stringify(data.a) === "\"Hello\""); // true
Otherwise, you'll likely need to run responseText through a lexer to tokenize it and retrieve the literal from that. JavaScript doesn't include an option for this separate from parsing/evaluating, so you'll need to find a library for this.
"Lexer written in JavaScript?" may be a good place to start for that.
To parse it:
Since it appears to be a string of code, you'll likely have to use eval().
var data = eval('(' + xx.responseText + ')');
console.log(data.a); // Hello
Note: The parenthesis make sure {...} is evaluated as an Object literal rather than as a block.
Also, I'd suggest looking into alternatives to code for communicating data like this.
A common option is JSON, which takes its syntax from JavaScript, but uses a rather strict subset. It doesn't allow functions or other potentially problematic code to be included.
var data = JSON.parse(xx.responseText);
console.log(data.a); // Hello
Visiting JSON.org, you should be able to find a reference or library for the choice of server-side language to output JSON.
{ "a": "Hello" }
Why not just let the JSON parser do its job and handle the \x escape sequences, and then just convert the string back to hex again afterwards, e.g.
function charToHex(c) {
var hex = c.charCodeAt(0).toString(16);
return (hex.length === 2) ? hex : '0' + hex;
}
"Hello".replace(/./g, charToHex); // gives "48656c6c6f"

Parse ill formed JSON string

I am being sent an ill formed JSON string from a third party. I tried using JSON.parse(str) to parse it into a JavaScript object but it of course failed.
The reason being is that the keys are not strings:
{min: 100}
As opposed to valid JSON string (which parses just fine):
{"min": 100}
I need to accept the ill formed string for now. I imagine forgetting to properly quote keys is a common mistake. Is there a good way to change this to a valid JSON string so that I can parse it? For now I may have to parse character by character and try and form an object, which sounds awful.
Ideas?
You could just eval, but that would be bad security practice if you don't trust the source. Better solution would be to either modify the string manually to quote the keys or use a tool someone else has written that does this for you (check out https://github.com/daepark/JSOL written by daepark).
I did this just recently, using Uglifyjs to evaluate:
var jsp = require("uglify-js").parser;
var pro = require("uglify-js").uglify;
var orig_code = "var myobject = " + badJSONobject;
var ast = jsp.parse(orig_code); // parse code and get the initial AST
var final_code = pro.gen_code(ast); // regenerate code
$('head').append('<script>' + final_code + '; console.log(JSON.stringify(myobject));</script>');
This is really sloppy in a way, and has all the same problems as an eval() based solution, but if you just need to parse/reformat the data one time, then the above should get you a clean JSON copy of the JS object.
Depending on what else is in the JSON, you could simply do a string replace and replace '{' with '{"' and ':' with '":'.

unicode to utf-8 in JavaScript

i have output from a server like
["alex", "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd"]
i want to convert it like
["alex", "to its right language"]
using js or jquery
i tried
function encode_utf8( s )
{
return unescape( encodeURIComponent( s ) )
}
but not working correctly
any help?
thanks in advance
I am not sure about what you mean by getting output "LIKE" the shown example...
but if you get ["alex", "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd"] and assign it to a variable like
var foo = ["alex", "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd"];
// alert(foo[1]) results in "��������" which actually means
// the engine has at least tried to resolve the characters
for example if you pass in correct character codes like:
var foo = ["alex", "\u003cp\u003emy UTF paragraph\u003c/p\u003e"];
// alert(foo[1]) results in "<p>my UTF paragraph</p>" which seems correct to me...
Try the examples above in a browser console (works at least for me in current Chrome)
On the other hand if you receive "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd" every time then I assume similar to the commentors that your response already gets messed up before you are handling it in JavaScript
This article shows nicely that using Unicode characters is valid for variable naming so the same should apply to string content.

Javascript: Modify code to add elements to an array/list

Hey Guys,
Javascript newbie here. I'm trying to modify some existing to code to instead of returning the count of elements, to actually add each of the specified elements to an array/list
here is the original code from Selenium CSS counter
private int getCSSCount(String aCSSLocator){
String jsScript = "var cssMatches = eval_css(\"%s\", window.document);cssMatches.length;";
return Integer.parseInt(selenium.getEval(String.format(jsScript, aCSSLocator)));
}
I then have to convert the code to python, which I am far more familiar with
def count_css_matches(self, css_locator):
java_script_code = '''
var cssMatches = eval_css("%s", window.document);
cssMatches.length;''' % css_locator
return int(self.selenium.get_eval(java_script_code))
But changing the original code to return the array instead of an integer is where I get stuck.
Thanks for the help and the below is the error I get when I tried to run it in Python.
Traceback (most recent call last):
"D:\Temp\1TestingApps\Selenium\SeleniumRC\selenium-python-client-driver-1.0.1\selenium.py", line 1218, in get_eval
return self.get_string("getEval", [script,])
File "D:\Temp\1TestingApps\Selenium\SeleniumRC\selenium-python-client-driver-1.0.1\selenium.py", line 219, in get_string
result = self.do_command(verb, args)
File "D:\Temp\1TestingApps\Selenium\SeleniumRC\selenium-python-client-driver-1.0.1\selenium.py", line 215, in do_command
raise Exception, data
Exception: ERROR: Threw an exception: missing ) after argument list
I'm not sure how eval_css works, but if returns an array of strings into cssMatches, as you can get an string, and not a list, using get_eval, then you should JSONify the list in the JS scope, getting it as an string into python, and using simplejson, converting it to an python's native list.
Something like this, I guess:
import json
def count_css_matches(self, css_locator):
java_script_code = '''
var cssMatches = eval_css("%s", window.document);
JSON.stringify(cssMatches.length);''' % css_locator
return json.loads(self.selenium.get_eval(java_script_code)))
I don't know if you need a return, document.write, or something like that in the js code to get the string. Please add a comment if it's needed, and I'll add it to the code :-)
Good luck!
If you update your python bindings you will have it. pip install -U selenium

Categories