How to generate a random string containing only hex characters (0123456789abcdef) of a given length?
Short alternative using spread operator and .map()
Demo 1
const genRanHex = size => [...Array(size)].map(() => Math.floor(Math.random() * 16).toString(16)).join('');
console.log(genRanHex(6));
console.log(genRanHex(12));
console.log(genRanHex(3));
Pass in a number (size) for the length of the returned string.
Define an empty array (result) and an array of strings in the range of [0-9] and [a-f] (hexRef).
On each iteration of a for loop, generate a random number 0 to 15 and use it as the index of the value from the array of strings from step 2 (hexRef) -- then push() the value to the empty array from step 2 (result).
Return the array (result) as a join('')ed string.
Demo 2
const getRanHex = size => {
let result = [];
let hexRef = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
for (let n = 0; n < size; n++) {
result.push(hexRef[Math.floor(Math.random() * 16)]);
}
return result.join('');
}
console.log(getRanHex(6));
console.log(getRanHex(12));
console.log(getRanHex(3));
NodeJS Users
You can use randomBytes available in the crypto module, to generate cryptographically strong pseudorandom data of a given size. And you can easily convert it to hex.
import crypto from "crypto";
const randomString = crypto.randomBytes(8).toString("hex");
console.log(randomString) // ee48d32e6c724c4d
The above code snippet generates a random 8-bytes hex number, you can manipulate the length as you wish.
There are a few ways. One way is to just pull from a predefined string:
function genHexString(len) {
const hex = '0123456789ABCDEF';
let output = '';
for (let i = 0; i < len; ++i) {
output += hex.charAt(Math.floor(Math.random() * hex.length));
}
return output;
}
The other way is to append a random number between 0 and 15 converted to hex with toString:
function genHexString(len) {
let output = '';
for (let i = 0; i < len; ++i) {
output += (Math.floor(Math.random() * 16)).toString(16);
}
return output;
}
This securely generates a 32-byte random string and encodes it as hex (64 characters).
Array.from(crypto.getRandomValues(new Uint8Array(32)))
.map(b => b.toString(16).padStart(2, '0')).join('');
Long version:
function generateRandomHexString(numBytes) {
const bytes = crypto.getRandomValues(new Uint8Array(numBytes));
const array = Array.from(bytes);
const hexPairs = array.map(b => b.toString(16).padStart(2, '0'));
return hexPairs.join('')
}
If you can use lodash library here is the code snippet to generate a 16 chars string:
let randomString = _.times(16, () => (Math.random()*0xF<<0).toString(16)).join('');
You can use a hexa number 0xfffff to random a hex string
getHexaNumb() {
return Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, "0")
}
Length of the array is the length of the random string.
const randomHex = Array.from({ length: 32 }, () => "0123456789ABCDEF".charAt(Math.floor(Math.random() * 16))).join('');
console.log(randomHex);
Here's a version that avoids building one digit at a time; it's probably only suitable for short lengths.
function genHexString(len) {
const str = Math.floor(Math.random() * Math.pow(16, len)).toString(16);
return "0".repeat(len - str.length) + str;
}
This works for lengths up to 13:
randomHex = length => (
'0'.repeat(length)
+ Math.floor((Math.random() * 16 ** length))
.toString(16)
).slice(-length);
console.log(randomHex(4));
console.log(randomHex(6));
console.log(randomHex(13));
console.log(randomHex(20));
Up to 7 characters may be quickly taken from one Math.random() call (A):
const halfBytesIn35 = 7 // = 3.5 bytes
const byte35 = Math.pow(16, halfBytesIn35)
const bytes35 = () => ((Math.random() * byte35) | 0).toString(16).padStart(halfBytesIn35,'0')
console.log('A: ' + bytes35())
const bytes65 = len => Math.floor(Math.random() * Math.pow(16, len*2)).toString(16).padStart(len,'0')
console.log('B: ' + bytes65(6))
function moreBytes (len) {
len *= 2; // alternative: len <<= 1 if you do not use half bytes. This might allow optimizations based on len always being an Integer then.
let builder = "";
while (len > 0) {
builder += bytes35()
len -= 7
}
return builder.slice(0,len)
}
console.log('C: ' + moreBytes(16))
Store the Math.pow constant if you plan to use this with high frequency.
An 8th letter overflows into the sign bit in the binary floor.
You can reach up to 13 characters from one call by using Math.floor instead (B) or even loop the generator for an arbitrary length (C).
Note that this could be used to define premature optimization. If your bottleneck really is the creation of Random Numbers consider using LUTs. This is common if you are developing for embedded. (And in this case somehow got stuck using javascript, but do not have the timebuget to generate random Numbers)
Using for Loop, charAt and Math.random
let result = "";
let hexChar = "0123456789abcdef";
for (var i = 0; i < 6; i++) {
result += hexChar.charAt(Math.floor(Math.random() * hexChar.length));
}
console.log(`#${result}`);
Using Math.random, you can do 13 characters at a time in a convenient way. If you want an arbitrary length string, you can still do it with a "one-liner":
const makeRandomHexString = (length: number) =>
Array.from({ length: Math.ceil(length / 13) })
.map(() =>
Math.floor(Math.random() * (Number.MAX_SAFE_INTEGER / 2))
.toString(16)
.padStart(13, '0')
)
.join('')
.substring(0, length);
Here is a simplified program to generate random hexadecimal Colour code:
let items = ["a", "b", "c", "d", "e", "f"];
let item = items[Math.floor(Math.random() * items.length)];
console.log(item);
let random = Math.random().toString().slice(2, 6);
console.log(`#${item}${random}${item}`);
let generateMacAdd = (function () {
let hexas = '0123456789ABCDEF'
let storeMac = []
let i = 0
do {
let random1st = hexas.charAt(Math.floor(Math.random() * hexas.length))
let random2nd = hexas.charAt(Math.floor(Math.random() * hexas.length))
storeMac.push(random1st + random2nd)
i++
} while (i <= 6)
return storeMac.join(':')
})()
console.log(generateMacAdd); //will generate a formatted mac address
I use self invoking function here so you can just call the variable
w/o any arguments
I also use do while here, just for my own convenience, you can do
any kind of loop depends what you're comfortable
I am trying to add two decimal numbers (arguments could be numbers or strings that are numbers before they are parsed) and compare the outcome with the resultInput. The problem is that the floating-point numbers cannot be represented accurately enough by the system. For example, 0.1 + 0.2 = 0.30000000000000004. So, I am trying to use toFixed() method to format a number using fixed-point notation. I am getting false when I run the code. Not sure where I am getting it wrong. Let me know if you have any ideas.
function calc(firstNumber, secondNumber, operation, resultInput) {
let a = parseFloat(firstNumber); //Number()
let b = parseFloat(secondNumber); //Number()
let c;
let d = parseFloat(resultInput);
console.log(JSON.stringify(`value of d : ${d}`)); //"value of d : NaN"
switch (operation) {
case '+':
c = a + b;
break;
case '-':
c = a - b;
break;
case '*':
c = a * b;
break;
case '/':
if (b === 0 && 1 / b === -Infinity) {
r = Infinity;
} else {
r = a / b;
}
break;
default:
console.log(`Sorry, wrong operator: ${operation}.`);
}
console.log(JSON.stringify(`value of c: ${c}`)); // "value of c: 0.30000000000000004"
let f = +c.toFixed(1);
let e = +d.toFixed(1);
console.log(JSON.stringify(`value of f: ${f}`)); // "value of f: 0.3"
console.log(typeof f); //number
console.log(JSON.stringify(`value of d: ${d}`)); // "value of d: NaN"
console.log(typeof d); //number
console.log(JSON.stringify(`value of e: ${e}`)); // "value of e: NaN"
console.log(typeof e); //number
if (f !== e) return false;
// if (!Object.is(f, e)) return false;
return true;
}
console.log(calc('0.1', '0.2', '+', '0.3'));
Rather than converting back and forth to/from strings, you can create a function that tests if two numbers are close enough to be called equal. You decide some small delta and if the numbers are at least that close, you call it good.
function almost(a, b, delta = 0.000001){
return Math.abs(a - b) < delta
}
// not really equal
console.log("equal?", 0.2 + 0.1 === 0.3)
// but good enough
console.log("close enough?", almost(0.2 + 0.1, 0.3))
I run your code several times and there is no problem with it. I just found that the '0.3' that you posted, it has an special character that looks like 3 but its not 3. So, when you want to run it on JS it will show an error. So your solution was correct. Check here.
function calc(firstNumber, secondNumber, operation, resultInput) {
let a = parseFloat(firstNumber);
let b = parseFloat(secondNumber);
let aux = parseFloat(resultInput);
let r;
switch (operation) {
case '+':
r = a + b;
break;
case '-':
r = a - b;
break;
case '*':
r = a * b;
break;
case '/':
if (b !== 0) {
r = a / b;
} else {
r = 0;
}
break;
default:
console.log(`Sorry, wrong operator: ${operation}.`);
}
return (+r.toFixed(1)) === (+aux.toFixed(1));
}
console.log(calc('0.1', '0.2', '+', '0.3'));
This is not an direct answer, but an explanation about toFixed() and behavior of floating point numbers:
toFixed() returns a text. One reason is, that generally no number exists, the can represent the result of toFixed(). So use this function only for displaying, but not for calculating like here.
let f = +c.toFixed(1);
let e = +d.toFixed(1);
toPrecision(18) is good to display all relevant digits of a number. Some examples:
(0.1).toPrecision(18) // => 0.100000000000000006
(0.2).toPrecision(18) // => 0.200000000000000011
(0.3).toPrecision(18) // => 0.299999999999999989
The examples explains, why 0.1+0.2 is not the same as 0.3.
Same examples with toFixed(1):
(+(0.1).toFixed(1)).toPrecision(18) // => 0.100000000000000006
(+(0.2).toFixed(1)).toPrecision(18) // => 0.200000000000000011
(+(0.3).toFixed(1)).toPrecision(18) // => 0.299999999999999989
It changed nothing: toFixed(1) formats the number, and the + sign convert it back to the nearest existing number.
This is not a JavaScript issue, it is an issue of computer based floating points number using IEEE 754 (binary based numbers). Most hardware support this kind of floats.
In computer mathematics it is usual, to compare equality of floating point numbers by using absolute or relative delta values. Example for absolute delta:
function isEqual( num1, num2, epsilon )
{
return Math.abs( num1 - num2 ) <= epsilon;
}
isEqual( 0.1 + 0.2, 0.3, 1e-10 ) // => true
Databases support dataytpes like DECIMAL(5.1). Here 0.1+0.2 == 0.3, because the use internally interger numbers and format only the output.
JavaScript example for currency with 2 fraction digits (euro,cent):
// scan user input:
cent = round( euro * 100 );
// adding cents:
cent3 = cent1 + cent2;
// print cents as euro
(cent/100).toFixed(2)+"€"
var toyProblem = function () {
var sol= 0;
var operators = ['+','-','*','/'];
console.log(sol)
for(var i in arguments){
for(var j in operators){
sol = eval(sol + (operators[j]) + arguments[i]);
}
}
return sol;
}
toyProblem(6, 0, 10, 3); //6 + 0 - 10 * 3 === -12)
I'm trying to loop through 4 math operators for an unknown number of input values. I'm thinking of using eval in a nest for loop as a way of going through both the unknown number of arguments while also changing the math operator. At the bottom is the solution that I want to arrive at. Is this a good way of going about this problem or am I barking up the wrong tree?
var toyProblem = function () {
var sol_str='';
var operators = ['+','-','*','/'];
for(var i in operators){
var prev_operator=(i-1);
if(sol_str!=''){sol_str+=operators[prev_operator];}
sol_str +=arguments[i];
}
console.log(sol_str);
return eval(sol_str);
}
console.log(toyProblem(6, 0, 10, 3));
Nesting the 2 loops will result in doing 6 + 6 - 6 * 6 / 6 + 0 - 0 * 0 / 0 + 10 - 10 * 10 / 10 + 3 - 3 * 3 / 3
I didn't find a way to do this without eval as looping through operations one by one would modify the operators priority so this is what I propose : Building an operation 'query' to be eval'd and returned.
Hope this helps
var toyProblem = function () {
var operation = '';
var operators = ['+','-','*','/'];
var args = Array.from(arguments);
args.forEach(function (arg, index) {
if (index > 0) {
operation += operators[index - 1];
}
operation += arg;
});
return eval(operation);
}
console.log(6 + 0 - 10 * 3);
console.log(toyProblem(6, 0, 10, 3)); //6 + 0 - 10 * 3 === -24)
Let's decompose the problem. You have a variadic function that accepts unknown number of arguments and applies an operator to each next argument depending on the index of that element.
Because the number of arguments can be greater than the number of operators, it's appropriate to use modulo operator to infinitely loop through the array of operators while going once through the list of arguments.
The eval operation takes a string, evaluates it, and returns the result of evaluation of the expression that string represents. So you're on the right track. But because eval function takes a string as the first argument, I'd recommend using template literals, it's supported in almost all browsers natively and doesn't need to be transpiled into good old ES5.
The function then would look like this:
function toyProblem(first = 0, ...args) {
const operators = ['+', '-', '*', '/'];
let sol = first;
for (let i in args) {
sol = eval(`${sol} ${operators[i % operators.length]} ${args[i]}`);
}
return sol;
}
However, as there is recommended in the comments, using eval isn't something you'd like to ship to users. Instead, I'd suggest using functions. Functions in Javascript are first-class citizens, so you can pass them as an argument.
Imagine that you have a function (a, b) => a + b instead of just a string "+". The code would then look like this:
function toyProblem(first = 0, ...args) {
const operations = [
(a, b) => a + b,
(a, b) => a - b,
(a, b) => a * b,
(a, b) => a / b,
];
let sol = first;
for (let i in args) {
sol = operations[i](sol, args[i]);
}
return sol;
}
You could go even further and make the function universal in terms of possible operations. Have fun!
Since you are hard coding the names of the operators you might as well hard code the functions and avoid eval. You put the functions into an array that will let you loop through. Then you can just reduce through the arguments with a simple one-liner, which will handle any amount of arguments:
const op = [
(a, b) => a + b,
(a, b) => a - b,
(a, b) => a * b,
(a, b) => a / b
]
function prob(...args){
return args.reduce((curr, acc, idx) => op[(idx - 1) % op.length](curr, acc))
}
console.log(prob(6, 0, 10, 3))
console.log(prob(6, 0, 10, 3, 20, 11, 15, 100))
To get product -12 the first three parts of the expression need to be evaluated within parentheses, else the result will be -24. You can use String.prototype.replace() to replace "," characters after calling .toString() on input array, replace the "," with the operator, return the expression (6 + 0 - 10) * 3 from Function() constructor
var toyProblem = function () {
var operators = ['+','-','*'];
var opts = operators.slice(0);
var n = [...arguments];
var res = n.toString().replace(/,/g, () => opts.shift());
var index = res.indexOf(operators[operators.length -1]);
return new Function(`return (${res.slice(0, index)})${res.slice(index)}`)();
}
var product = toyProblem(6, 0, 10, 3);
console.log(product);
How do you convert decimal values to their hexadecimal equivalent in JavaScript?
Convert a number to a hexadecimal string with:
hexString = yourNumber.toString(16);
And reverse the process with:
yourNumber = parseInt(hexString, 16);
If you need to handle things like bit fields or 32-bit colors, then you need to deal with signed numbers. The JavaScript function toString(16) will return a negative hexadecimal number which is usually not what you want. This function does some crazy addition to make it a positive number.
function decimalToHexString(number)
{
if (number < 0)
{
number = 0xFFFFFFFF + number + 1;
}
return number.toString(16).toUpperCase();
}
console.log(decimalToHexString(27));
console.log(decimalToHexString(48.6));
The code below will convert the decimal value d to hexadecimal. It also allows you to add padding to the hexadecimal result. So 0 will become 00 by default.
function decimalToHex(d, padding) {
var hex = Number(d).toString(16);
padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding;
while (hex.length < padding) {
hex = "0" + hex;
}
return hex;
}
function toHex(d) {
return ("0"+(Number(d).toString(16))).slice(-2).toUpperCase()
}
For completeness, if you want the two's-complement hexadecimal representation of a negative number, you can use the zero-fill-right shift >>> operator. For instance:
> (-1).toString(16)
"-1"
> ((-2)>>>0).toString(16)
"fffffffe"
There is however one limitation: JavaScript bitwise operators treat their operands as a sequence of 32 bits, that is, you get the 32-bits two's complement.
With padding:
function dec2hex(i) {
return (i+0x10000).toString(16).substr(-4).toUpperCase();
}
The accepted answer did not take into account single digit returned hexadecimal codes. This is easily adjusted by:
function numHex(s)
{
var a = s.toString(16);
if ((a.length % 2) > 0) {
a = "0" + a;
}
return a;
}
and
function strHex(s)
{
var a = "";
for (var i=0; i<s.length; i++) {
a = a + numHex(s.charCodeAt(i));
}
return a;
}
I believe the above answers have been posted numerous times by others in one form or another. I wrap these in a toHex() function like so:
function toHex(s)
{
var re = new RegExp(/^\s*(\+|-)?((\d+(\.\d+)?)|(\.\d+))\s*$/);
if (re.test(s)) {
return '#' + strHex( s.toString());
}
else {
return 'A' + strHex(s);
}
}
Note that the numeric regular expression came from 10+ Useful JavaScript Regular Expression Functions to improve your web applications efficiency.
Update: After testing this thing several times I found an error (double quotes in the RegExp), so I fixed that. HOWEVER! After quite a bit of testing and having read the post by almaz - I realized I could not get negative numbers to work.
Further - I did some reading up on this and since all JavaScript numbers are stored as 64 bit words no matter what - I tried modifying the numHex code to get the 64 bit word. But it turns out you can not do that. If you put "3.14159265" AS A NUMBER into a variable - all you will be able to get is the "3", because the fractional portion is only accessible by multiplying the number by ten(IE:10.0) repeatedly. Or to put that another way - the hexadecimal value of 0xF causes the floating point value to be translated into an integer before it is ANDed which removes everything behind the period. Rather than taking the value as a whole (i.e.: 3.14159265) and ANDing the floating point value against the 0xF value.
So the best thing to do, in this case, is to convert the 3.14159265 into a string and then just convert the string. Because of the above, it also makes it easy to convert negative numbers because the minus sign just becomes 0x26 on the front of the value.
So what I did was on determining that the variable contains a number - just convert it to a string and convert the string. This means to everyone that on the server side you will need to unhex the incoming string and then to determine the incoming information is numeric. You can do that easily by just adding a "#" to the front of numbers and "A" to the front of a character string coming back. See the toHex() function.
Have fun!
After another year and a lot of thinking, I decided that the "toHex" function (and I also have a "fromHex" function) really needed to be revamped. The whole question was "How can I do this more efficiently?" I decided that a to/from hexadecimal function should not care if something is a fractional part but at the same time it should ensure that fractional parts are included in the string.
So then the question became, "How do you know you are working with a hexadecimal string?". The answer is simple. Use the standard pre-string information that is already recognized around the world.
In other words - use "0x". So now my toHex function looks to see if that is already there and if it is - it just returns the string that was sent to it. Otherwise, it converts the string, number, whatever. Here is the revised toHex function:
/////////////////////////////////////////////////////////////////////////////
// toHex(). Convert an ASCII string to hexadecimal.
/////////////////////////////////////////////////////////////////////////////
toHex(s)
{
if (s.substr(0,2).toLowerCase() == "0x") {
return s;
}
var l = "0123456789ABCDEF";
var o = "";
if (typeof s != "string") {
s = s.toString();
}
for (var i=0; i<s.length; i++) {
var c = s.charCodeAt(i);
o = o + l.substr((c>>4),1) + l.substr((c & 0x0f),1);
}
return "0x" + o;
}
This is a very fast function that takes into account single digits, floating point numbers, and even checks to see if the person is sending a hex value over to be hexed again. It only uses four function calls and only two of those are in the loop. To un-hex the values you use:
/////////////////////////////////////////////////////////////////////////////
// fromHex(). Convert a hex string to ASCII text.
/////////////////////////////////////////////////////////////////////////////
fromHex(s)
{
var start = 0;
var o = "";
if (s.substr(0,2).toLowerCase() == "0x") {
start = 2;
}
if (typeof s != "string") {
s = s.toString();
}
for (var i=start; i<s.length; i+=2) {
var c = s.substr(i, 2);
o = o + String.fromCharCode(parseInt(c, 16));
}
return o;
}
Like the toHex() function, the fromHex() function first looks for the "0x" and then it translates the incoming information into a string if it isn't already a string. I don't know how it wouldn't be a string - but just in case - I check. The function then goes through, grabbing two characters and translating those in to ASCII characters. If you want it to translate Unicode, you will need to change the loop to going by four(4) characters at a time. But then you also need to ensure that the string is NOT divisible by four. If it is - then it is a standard hexadecimal string. (Remember the string has "0x" on the front of it.)
A simple test script to show that -3.14159265, when converted to a string, is still -3.14159265.
<?php
echo <<<EOD
<html>
<head><title>Test</title>
<script>
var a = -3.14159265;
alert( "A = " + a );
var b = a.toString();
alert( "B = " + b );
</script>
</head>
<body>
</body>
</html>
EOD;
?>
Because of how JavaScript works in respect to the toString() function, all of those problems can be eliminated which before were causing problems. Now all strings and numbers can be converted easily. Further, such things as objects will cause an error to be generated by JavaScript itself. I believe this is about as good as it gets. The only improvement left is for W3C to just include a toHex() and fromHex() function in JavaScript.
Without the loop:
function decimalToHex(d) {
var hex = Number(d).toString(16);
hex = "000000".substr(0, 6 - hex.length) + hex;
return hex;
}
// Or "#000000".substr(0, 7 - hex.length) + hex;
// Or whatever
// *Thanks to MSDN
Also isn't it better not to use loop tests that have to be evaluated?
For example, instead of:
for (var i = 0; i < hex.length; i++){}
have
for (var i = 0, var j = hex.length; i < j; i++){}
Combining some of these good ideas for an RGB-value-to-hexadecimal function (add the # elsewhere for HTML/CSS):
function rgb2hex(r,g,b) {
if (g !== undefined)
return Number(0x1000000 + r*0x10000 + g*0x100 + b).toString(16).substring(1);
else
return Number(0x1000000 + r[0]*0x10000 + r[1]*0x100 + r[2]).toString(16).substring(1);
}
Constrained/padded to a set number of characters:
function decimalToHex(decimal, chars) {
return (decimal + Math.pow(16, chars)).toString(16).slice(-chars).toUpperCase();
}
For anyone interested, here's a JSFiddle comparing most of the answers given to this question.
And here's the method I ended up going with:
function decToHex(dec) {
return (dec + Math.pow(16, 6)).toString(16).substr(-6)
}
Also, bear in mind that if you're looking to convert from decimal to hex for use in CSS as a color data type, you might instead prefer to extract the RGB values from the decimal and use rgb().
For example (JSFiddle):
let c = 4210330 // your color in decimal format
let rgb = [(c & 0xff0000) >> 16, (c & 0x00ff00) >> 8, (c & 0x0000ff)]
// Vanilla JS:
document.getElementById('some-element').style.color = 'rgb(' + rgb + ')'
// jQuery:
$('#some-element').css('color', 'rgb(' + rgb + ')')
This sets #some-element's CSS color property to rgb(64, 62, 154).
var number = 3200;
var hexString = number.toString(16);
The 16 is the radix and there are 16 values in a hexadecimal number :-)
function dec2hex(i)
{
var result = "0000";
if (i >= 0 && i <= 15) { result = "000" + i.toString(16); }
else if (i >= 16 && i <= 255) { result = "00" + i.toString(16); }
else if (i >= 256 && i <= 4095) { result = "0" + i.toString(16); }
else if (i >= 4096 && i <= 65535) { result = i.toString(16); }
return result
}
If you want to convert a number to a hexadecimal representation of an RGBA color value, I've found this to be the most useful combination of several tips from here:
function toHexString(n) {
if(n < 0) {
n = 0xFFFFFFFF + n + 1;
}
return "0x" + ("00000000" + n.toString(16).toUpperCase()).substr(-8);
}
AFAIK comment 57807 is wrong and should be something like:
var hex = Number(d).toString(16);
instead of
var hex = parseInt(d, 16);
function decimalToHex(d, padding) {
var hex = Number(d).toString(16);
padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding;
while (hex.length < padding) {
hex = "0" + hex;
}
return hex;
}
And if the number is negative?
Here is my version.
function hexdec (hex_string) {
hex_string=((hex_string.charAt(1)!='X' && hex_string.charAt(1)!='x')?hex_string='0X'+hex_string : hex_string);
hex_string=(hex_string.charAt(2)<8 ? hex_string =hex_string-0x00000000 : hex_string=hex_string-0xFFFFFFFF-1);
return parseInt(hex_string, 10);
}
As the accepted answer states, the easiest way to convert from decimal to hexadecimal is var hex = dec.toString(16). However, you may prefer to add a string conversion, as it ensures that string representations like "12".toString(16) work correctly.
// Avoids a hard-to-track-down bug by returning `c` instead of `12`
(+"12").toString(16);
To reverse the process you may also use the solution below, as it is even shorter.
var dec = +("0x" + hex);
It seems to be slower in Google Chrome and Firefox, but is significantly faster in Opera. See http://jsperf.com/hex-to-dec.
I'm doing conversion to hex string in a pretty large loop, so I tried several techniques in order to find the fastest one. My requirements were to have a fixed-length string as a result, and encode negative values properly (-1 => ff..f).
Simple .toString(16) didn't work for me since I needed negative values to be properly encoded. The following code is the quickest I've tested so far on 1-2 byte values (note that symbols defines the number of output symbols you want to get, that is for 4-byte integer it should be equal to 8):
var hex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
function getHexRepresentation(num, symbols) {
var result = '';
while (symbols--) {
result = hex[num & 0xF] + result;
num >>= 4;
}
return result;
}
It performs faster than .toString(16) on 1-2 byte numbers and slower on larger numbers (when symbols >= 6), but still should outperform methods that encode negative values properly.
Converting hex color numbers to hex color strings:
A simple solution with toString and ES6 padStart for converting hex color numbers to hex color strings.
const string = `#${color.toString(16).padStart(6, '0')}`;
For example:
0x000000 will become #000000
0xFFFFFF will become #FFFFFF
Check this example in a fiddle here
How to convert decimal to hexadecimal in JavaScript
I wasn't able to find a brutally clean/simple decimal to hexadecimal conversion that didn't involve a mess of functions and arrays ... so I had to make this for myself.
function DecToHex(decimal) { // Data (decimal)
length = -1; // Base string length
string = ''; // Source 'string'
characters = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' ]; // character array
do { // Grab each nibble in reverse order because JavaScript has no unsigned left shift
string += characters[decimal & 0xF]; // Mask byte, get that character
++length; // Increment to length of string
} while (decimal >>>= 4); // For next character shift right 4 bits, or break on 0
decimal += 'x'; // Convert that 0 into a hex prefix string -> '0x'
do
decimal += string[length];
while (length--); // Flip string forwards, with the prefixed '0x'
return (decimal); // return (hexadecimal);
}
/* Original: */
D = 3678; // Data (decimal)
C = 0xF; // Check
A = D; // Accumulate
B = -1; // Base string length
S = ''; // Source 'string'
H = '0x'; // Destination 'string'
do {
++B;
A& = C;
switch(A) {
case 0xA: A='A'
break;
case 0xB: A='B'
break;
case 0xC: A='C'
break;
case 0xD: A='D'
break;
case 0xE: A='E'
break;
case 0xF: A='F'
break;
A = (A);
}
S += A;
D >>>= 0x04;
A = D;
} while(D)
do
H += S[B];
while (B--)
S = B = A = C = D; // Zero out variables
alert(H); // H: holds hexadecimal equivalent
You can do something like this in ECMAScript 6:
const toHex = num => (num).toString(16).toUpperCase();
If you are looking for converting Large integers i.e. Numbers greater than Number.MAX_SAFE_INTEGER -- 9007199254740991, then you can use the following code
const hugeNumber = "9007199254740991873839" // Make sure its in String
const hexOfHugeNumber = BigInt(hugeNumber).toString(16);
console.log(hexOfHugeNumber)
To sum it all up;
function toHex(i, pad) {
if (typeof(pad) === 'undefined' || pad === null) {
pad = 2;
}
var strToParse = i.toString(16);
while (strToParse.length < pad) {
strToParse = "0" + strToParse;
}
var finalVal = parseInt(strToParse, 16);
if ( finalVal < 0 ) {
finalVal = 0xFFFFFFFF + finalVal + 1;
}
return finalVal;
}
However, if you don't need to convert it back to an integer at the end (i.e. for colors), then just making sure the values aren't negative should suffice.
I haven't found a clear answer, without checks if it is negative or positive, that uses two's complement (negative numbers included). For that, I show my solution to one byte:
((0xFF + number +1) & 0x0FF).toString(16);
You can use this instruction to any number bytes, only you add FF in respective places. For example, to two bytes:
((0xFFFF + number +1) & 0x0FFFF).toString(16);
If you want cast an array integer to string hexadecimal:
s = "";
for(var i = 0; i < arrayNumber.length; ++i) {
s += ((0xFF + arrayNumber[i] +1) & 0x0FF).toString(16);
}
In case you're looking to convert to a 'full' JavaScript or CSS representation, you can use something like:
numToHex = function(num) {
var r=((0xff0000&num)>>16).toString(16),
g=((0x00ff00&num)>>8).toString(16),
b=(0x0000ff&num).toString(16);
if (r.length==1) { r = '0'+r; }
if (g.length==1) { g = '0'+g; }
if (b.length==1) { b = '0'+b; }
return '0x'+r+g+b; // ('#' instead of'0x' for CSS)
};
var dec = 5974678;
console.log( numToHex(dec) ); // 0x5b2a96
This is based on Prestaul and Tod's solutions. However, this is a generalisation that accounts for varying size of a variable (e.g. Parsing signed value from a microcontroller serial log).
function decimalToPaddedHexString(number, bitsize)
{
let byteCount = Math.ceil(bitsize/8);
let maxBinValue = Math.pow(2, bitsize)-1;
/* In node.js this function fails for bitsize above 32bits */
if (bitsize > 32)
throw "number above maximum value";
/* Conversion to unsigned form based on */
if (number < 0)
number = maxBinValue + number + 1;
return "0x"+(number >>> 0).toString(16).toUpperCase().padStart(byteCount*2, '0');
}
Test script:
for (let n = 0 ; n < 64 ; n++ ) {
let s=decimalToPaddedHexString(-1, n);
console.log(`decimalToPaddedHexString(-1,${(n+"").padStart(2)}) = ${s.padStart(10)} = ${("0b"+parseInt(s).toString(2)).padStart(34)}`);
}
Test results:
decimalToPaddedHexString(-1, 0) = 0x0 = 0b0
decimalToPaddedHexString(-1, 1) = 0x01 = 0b1
decimalToPaddedHexString(-1, 2) = 0x03 = 0b11
decimalToPaddedHexString(-1, 3) = 0x07 = 0b111
decimalToPaddedHexString(-1, 4) = 0x0F = 0b1111
decimalToPaddedHexString(-1, 5) = 0x1F = 0b11111
decimalToPaddedHexString(-1, 6) = 0x3F = 0b111111
decimalToPaddedHexString(-1, 7) = 0x7F = 0b1111111
decimalToPaddedHexString(-1, 8) = 0xFF = 0b11111111
decimalToPaddedHexString(-1, 9) = 0x01FF = 0b111111111
decimalToPaddedHexString(-1,10) = 0x03FF = 0b1111111111
decimalToPaddedHexString(-1,11) = 0x07FF = 0b11111111111
decimalToPaddedHexString(-1,12) = 0x0FFF = 0b111111111111
decimalToPaddedHexString(-1,13) = 0x1FFF = 0b1111111111111
decimalToPaddedHexString(-1,14) = 0x3FFF = 0b11111111111111
decimalToPaddedHexString(-1,15) = 0x7FFF = 0b111111111111111
decimalToPaddedHexString(-1,16) = 0xFFFF = 0b1111111111111111
decimalToPaddedHexString(-1,17) = 0x01FFFF = 0b11111111111111111
decimalToPaddedHexString(-1,18) = 0x03FFFF = 0b111111111111111111
decimalToPaddedHexString(-1,19) = 0x07FFFF = 0b1111111111111111111
decimalToPaddedHexString(-1,20) = 0x0FFFFF = 0b11111111111111111111
decimalToPaddedHexString(-1,21) = 0x1FFFFF = 0b111111111111111111111
decimalToPaddedHexString(-1,22) = 0x3FFFFF = 0b1111111111111111111111
decimalToPaddedHexString(-1,23) = 0x7FFFFF = 0b11111111111111111111111
decimalToPaddedHexString(-1,24) = 0xFFFFFF = 0b111111111111111111111111
decimalToPaddedHexString(-1,25) = 0x01FFFFFF = 0b1111111111111111111111111
decimalToPaddedHexString(-1,26) = 0x03FFFFFF = 0b11111111111111111111111111
decimalToPaddedHexString(-1,27) = 0x07FFFFFF = 0b111111111111111111111111111
decimalToPaddedHexString(-1,28) = 0x0FFFFFFF = 0b1111111111111111111111111111
decimalToPaddedHexString(-1,29) = 0x1FFFFFFF = 0b11111111111111111111111111111
decimalToPaddedHexString(-1,30) = 0x3FFFFFFF = 0b111111111111111111111111111111
decimalToPaddedHexString(-1,31) = 0x7FFFFFFF = 0b1111111111111111111111111111111
decimalToPaddedHexString(-1,32) = 0xFFFFFFFF = 0b11111111111111111111111111111111
Thrown: 'number above maximum value'
Note: Not too sure why it fails above 32 bitsize
rgb(255, 255, 255) // returns FFFFFF
rgb(255, 255, 300) // returns FFFFFF
rgb(0,0,0) // returns 000000
rgb(148, 0, 211) // returns 9400D3
function rgb(...values){
return values.reduce((acc, cur) => {
let val = cur >= 255 ? 'ff' : cur <= 0 ? '00' : Number(cur).toString(16);
return acc + (val.length === 1 ? '0'+val : val);
}, '').toUpperCase();
}
Arbitrary precision
This solution take on input decimal string, and return hex string. A decimal fractions are supported. Algorithm
split number to sign (s), integer part (i) and fractional part (f) e.g for -123.75 we have s=true, i=123, f=75
integer part to hex:
if i='0' stop
get modulo: m=i%16 (in arbitrary precision)
convert m to hex digit and put to result string
for next step calc integer part i=i/16 (in arbitrary precision)
fractional part
count fractional digits n
multiply k=f*16 (in arbitrary precision)
split k to right part with n digits and put them to f, and left part with rest of digits and put them to d
convert d to hex and add to result.
finish when number of result fractional digits is enough
// #param decStr - string with non-negative integer
// #param divisor - positive integer
function dec2HexArbitrary(decStr, fracDigits=0) {
// Helper: divide arbitrary precision number by js number
// #param decStr - string with non-negative integer
// #param divisor - positive integer
function arbDivision(decStr, divisor)
{
// algorithm https://www.geeksforgeeks.org/divide-large-number-represented-string/
let ans='';
let idx = 0;
let temp = +decStr[idx];
while (temp < divisor) temp = temp * 10 + +decStr[++idx];
while (decStr.length > idx) {
ans += (temp / divisor)|0 ;
temp = (temp % divisor) * 10 + +decStr[++idx];
}
if (ans.length == 0) return "0";
return ans;
}
// Helper: calc module of arbitrary precision number
// #param decStr - string with non-negative integer
// #param mod - positive integer
function arbMod(decStr, mod) {
// algorithm https://www.geeksforgeeks.org/how-to-compute-mod-of-a-big-number/
let res = 0;
for (let i = 0; i < decStr.length; i++)
res = (res * 10 + +decStr[i]) % mod;
return res;
}
// Helper: multiply arbitrary precision integer by js number
// #param decStr - string with non-negative integer
// #param mult - positive integer
function arbMultiply(decStr, mult) {
let r='';
let m=0;
for (let i = decStr.length-1; i >=0 ; i--) {
let n = m+mult*(+decStr[i]);
r= (i ? n%10 : n) + r
m= n/10|0;
}
return r;
}
// dec2hex algorithm starts here
let h= '0123456789abcdef'; // hex 'alphabet'
let m= decStr.match(/-?(.*?)\.(.*)?/) || decStr.match(/-?(.*)/); // separate sign,integer,ractional
let i= m[1].replace(/^0+/,'').replace(/^$/,'0'); // integer part (without sign and leading zeros)
let f= (m[2]||'0').replace(/0+$/,'').replace(/^$/,'0'); // fractional part (without last zeros)
let s= decStr[0]=='-'; // sign
let r=''; // result
if(i=='0') r='0';
while(i!='0') { // integer part
r=h[arbMod(i,16)]+r;
i=arbDivision(i,16);
}
if(fracDigits) r+=".";
let n = f.length;
for(let j=0; j<fracDigits; j++) { // frac part
let k= arbMultiply(f,16);
f = k.slice(-n);
let d= k.slice(0,k.length-n);
r+= d.length ? h[+d] : '0';
}
return (s?'-':'')+r;
}
// -----------
// TESTS
// -----------
let tests = [
["0",2],
["000",2],
["123",0],
["-123",0],
["00.000",2],
["255.75",5],
["-255.75",5],
["127.999",32],
];
console.log('Input Standard Abitrary');
tests.forEach(t=> {
let nonArb = (+t[0]).toString(16).padEnd(17,' ');
let arb = dec2HexArbitrary(t[0],t[1]);
console.log(t[0].padEnd(10,' '), nonArb, arb);
});
// Long Example (40 digits after dot)
let example = "123456789012345678901234567890.09876543210987654321"
console.log(`\nLong Example:`);
console.log('dec:',example);
console.log('hex: ',dec2HexArbitrary(example,40));
The problem basically how many padding zeros to expect.
If you expect string 01 and 11 from Number 1 and 17. it's better to use Buffer as a bridge, with which number is turn into bytes, and then the hex is just an output format of it. And the bytes organization is well controlled by Buffer functions, like writeUInt32BE, writeInt16LE, etc.
import { Buffer } from 'buffer';
function toHex(n) { // 4byte
const buff = Buffer.alloc(4);
buff.writeInt32BE(n);
return buff.toString('hex');
}
> toHex(1)
'00000001'
> toHex(17)
'00000011'
> toHex(-1)
'ffffffff'
> toHex(-1212)
'fffffb44'
> toHex(1212)
'000004bc'
Here's my solution:
hex = function(number) {
return '0x' + Math.abs(number).toString(16);
}
The question says: "How to convert decimal to hexadecimal in JavaScript". While, the question does not specify that the hexadecimal string should begin with a 0x prefix, anybody who writes code should know that 0x is added to hexadecimal codes to distinguish hexadecimal codes from programmatic identifiers and other numbers (1234 could be hexadecimal, decimal, or even octal).
Therefore, to correctly answer this question, for the purpose of script-writing, you must add the 0x prefix.
The Math.abs(N) function converts negatives to positives, and as a bonus, it doesn't look like somebody ran it through a wood-chipper.
The answer I wanted, would have had a field-width specifier, so we could for example show 8/16/32/64-bit values the way you would see them listed in a hexadecimal editing application. That, is the actual, correct answer.