接受的答案未考虑返回的单个数字十六进制代码。这很容易通过以下方式调整:
function numHex(s)
{
var a = s.toString(16);
if ((a.length % 2) > 0) {
a = "0" + a;
}
return a;
}
和
function strHex(s)
{
var a = "";
for (var i=0; i<s.length; i++) {
a = a + numHex(s.charCodeAt(i));
}
return a;
}
我相信上述答案已被其他人以一种或另一种形式多次发布。我将它们包装在一个 toHex() 函数中,如下所示:
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);
}
}
请注意,数字正则表达式来自10+ Useful JavaScript Regular Expression Functions to improve your web applications efficiency。
更新:在多次测试这个东西后,我发现了一个错误(RegExp 中的双引号),所以我修复了它。然而!经过大量测试并阅读了 almaz 的帖子后,我意识到我无法让负数起作用。
进一步 - 我对此进行了一些阅读,因为无论如何所有 JavaScript 数字都存储为 64 位字 - 我尝试修改 numHex 代码以获取 64 位字。但事实证明你不能那样做。如果您将“3.14159265”作为数字放入变量中 - 您将能够得到的只是“3”,因为小数部分只能通过重复将数字乘以十(IE:10.0)来访问。或者换一种说法 - 0xF 的 hexadecimal 值导致 floating point 值在它被 ANDed 之前被转换为一个 integer期间的一切。而不是将值作为一个整体(即:3.14159265)并将 浮点 值与 0xF 值进行与运算。
因此,在这种情况下,最好的做法是将 3.14159265 转换为 字符串,然后再转换字符串。由于上述原因,负数的转换也很容易,因为减号正好变成了值前面的 0x26。
所以我所做的是确定变量包含一个数字 - 只需将其转换为字符串并转换字符串。这对每个人来说意味着,在服务器端,您需要对传入的字符串进行 unhex,然后确定传入的信息是数字的。您只需在数字前面添加“#”,在返回的字符串前面添加“A”即可轻松做到这一点。请参阅 toHex() 函数。
玩得开心!
又过了一年,经过深思熟虑,我决定真的需要改进“toHex”函数(我还有一个“fromHex”函数)。整个问题是“我怎样才能更有效地做到这一点?”我决定一个 to/from 十六进制函数不应该关心某些东西是否是小数部分,但同时它应该确保小数部分包含在字符串中。
那么问题就变成了,“你怎么知道你正在使用十六进制字符串?”。答案很简单。使用全球公认的标准前置字符串信息。
换句话说 - 使用“0x”。所以现在我的 toHex 函数查看它是否已经存在,如果它存在 - 它只返回发送给它的字符串。否则,它将转换字符串、数字等。下面是修改后的 toHex 函数:
/////////////////////////////////////////////////////////////////////////////
// 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;
}
这是一个非常快速的函数,它考虑了单个数字、浮点数,甚至可以检查该人是否正在发送一个十六进制值以再次进行十六进制处理。它只使用了四个函数调用,其中只有两个在循环中。要取消使用十六进制值:
/////////////////////////////////////////////////////////////////////////////
// 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;
}
与 toHex() 函数一样,fromHex() 函数首先查找“0x”,然后将传入的信息转换为字符串(如果它还不是字符串)。我不知道它怎么会不是一个字符串——但以防万一——我检查一下。然后该函数执行,抓取两个字符并将它们转换为 ASCII 字符。如果您希望它翻译 Unicode,您需要将循环更改为一次四 (4) 个字符。但是你还需要确保字符串不能被四整除。如果是 - 那么它是一个标准的十六进制字符串。 (记住字符串前面有“0x”。)
一个简单的测试脚本显示 -3.14159265 在转换为字符串后仍然是 -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;
?>
由于 JavaScript 相对于 toString() 函数的工作方式,所有这些问题都可以被消除,这些问题以前会引起问题。现在所有字符串和数字都可以轻松转换。此外,诸如对象之类的东西会导致 JavaScript 本身产生错误。我相信这是最好的。剩下的唯一改进是 W3C 在 JavaScript 中只包含一个 toHex() 和 fromHex() 函数。