В принятом ответе не учитываются однозначные возвращаемые шестнадцатеричные коды. Это легко регулируется:
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 + Полезные функции регулярных выражений JavaScript для повышения эффективности ваших веб-приложений .
Обновление: после тестирования этой вещи несколько раз я обнаружил ошибку (двойные кавычки в RegExp), поэтому я исправил это. ТЕМ НЕ МЕНИЕ! После небольшого тестирования и прочтения сообщения almaz - я понял, что не могу заставить работать отрицательные числа.
Далее - я немного прочитал об этом, и, поскольку все числа JavaScript хранятся как 64-битные слова, несмотря ни на что - я попытался изменить код numHex, чтобы получить 64-битное слово. Но, оказывается, ты не можешь этого сделать. Если вы поместите «3.14159265» КАК НОМЕР в переменную - все, что вы сможете получить, это «3», потому что дробная часть доступна только путем многократного умножения числа на десять (IE: 10.0). Или, другими словами, значение шестнадцатеричное , равное 0xF, приводит к тому, что значение с плавающей запятой переводится в целое число до того, как оно будет ANDed, которое удаляет все, что находится за период. Вместо того, чтобы брать значение в целом (т.е. 3.14159265) и ИЛИ значение с плавающей запятой против значения 0xF.
Поэтому в данном случае лучше всего преобразовать 3.14159265 в строку , а затем просто преобразовать строку. Из-за вышеизложенного это также упрощает преобразование отрицательных чисел, поскольку знак минус становится 0x26 в начале значения.
Итак, я определил, что переменная содержит число - просто преобразуйте его в строку и преобразуйте строку. Это значит для всех, что на стороне сервера вам нужно будет отсоединить входящую строку, а затем определить, что входящая информация является числовой. Вы можете сделать это легко, просто добавив "#" в начале чисел и "A" в начале строки символов, возвращающейся. Смотрите функцию toHex ().
Веселись!
После еще одного года и долгих раздумий я решил, что функцию "toHex" (а также функцию "fromHex") действительно нужно обновить. Весь вопрос был «Как я могу сделать это более эффективно?» Я решил, что шестнадцатеричная функция to / from не должна заботиться о том, является ли что-то дробной частью, но в то же время она должна гарантировать, что дробные части включены в строку.
И тогда возник вопрос: «Как вы узнаете, что работаете с шестнадцатеричной строкой?». Ответ прост. Используйте стандартную предварительную информацию, которая уже признана во всем мире.
Другими словами - используйте «0x». Так что теперь моя функция toHex проверяет, есть ли она там и есть ли она - она просто возвращает строку, которая была ему отправлена. В противном случае он преобразует строку, число, что угодно. Вот пересмотренная функция toHex:
////////////////////////////////////////////////// ///////////////////////////
// toHex (). Преобразовать строку ASCII в шестнадцатеричное.
////////////////////////////////////////////////// ///////////////////////////
toHex (ы)
{
if (s.substr (0,2) .toLowerCase () == "0x") {
возврат с;
}
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) == "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 ().