NAT является просто механизмом, он не определяет ограничений, и любой такой было бы совершенно зависящим от реализации. Я сомневаюсь, мог ли кто-либо даже дать приблизительное среднее число, поскольку существует столько реализаций NAT там. Этот вопрос действительно не имеет смысла.
В Системе с обратным порядком байтов (Солярис на SPARC)
$ echo -n I | od -to2 | head -n1 | cut -f2 -d" " | cut -c6
0
В небольшой системе порядка байтов (Linux на x86)
$ echo -n I | od -to2 | head -n1 | cut -f2 -d" " | cut -c6
1
Решение выше умно и работает отлично для Linux *86 и Sparc Solaris.
Мне был нужен только для оболочки (никакой Perl) решение, которое также работало над AIX/питанием и HPUX/Itanium. К сожалению, последние два не играют по правилам: AIX сообщает "6", и HPUX дает пустую строку.
Используя Ваше решение, я смог обработать что-то, что работало над всеми этими системами Unix:
$ echo I | tr -d [:space:] | od -to2 | head -n1 | awk '{print $2}' | cut -c6
Относительно решения Python кто-то отправил, оно не работает в Jython, потому что JVM рассматривает все как Большое. Если кто-либо может заставить это работать в Jython, отправьте!
Кроме того, я нашел это, которое объясняет порядок байтов различных платформ. Некоторые аппаратные средства могут работать в любом режиме в зависимости от того, что выбирает O/S: http://labs.hoffmanlabs.com/node/544
Если Вы собираетесь использовать awk, эта строка может быть упрощена до:
echo -n I | od -to2 | awk '{ print substr($2,6,1); exit}'
Для маленьких полей Linux, которые не имеют 'передозировки' (говорят, что OpenWrt) затем пробуют 'hexdump':
echo -n I | hexdump -o | awk '{ print substr($2,6,1); exit}'
Этот сценарий Python должен работать на Вас:
#!/usr/bin/env python
from struct import pack
if pack('@h', 1) == pack('<h', 1):
print "Little Endian"
else:
print "Big Endian"
Вот является более изящный Python коротким сценарием
python -c "import sys;sys.exit(0 if sys.byteorder=='big' else 1)"
код выхода 0
обратный порядок байтов средств и 1
прямой порядок байтов средств
или просто изменение sys.exit
кому: print
для печатаемого вывода
Я нашел способ сделать это в Jython. Поскольку Jython (Python на JVM) работает на виртуальной машине, он всегда сообщает обратный порядок байтов, независимо от оборудования.
Это решение работает для Linux, Solaris, AIX и HPUX. Не тестировал в Windows:
from java.lang import System
for property, value in dict(System.getProperties()).items():
if property.endswith('cpu.endian'):
return value
https://raid.wiki.kernel.org/index.php/RAID_superblock_formats
Суперблок имеет длину 4 КБ и записывается в выровненный блок размером 64 КБ, который начинается минимум 64 КБ и меньше 128 КБ от конца устройства (то есть, чтобы получить адрес суперблока размером с устройства до кратного 64 КБ, а затем вычесть 64 КБ). Доступные размер каждого устройства - это количество места перед суперблоком, поэтому между 64 КБ и 128 КБ теряется, когда устройство встроено в MD 19 пакета util-linux команда
lscpu
начала включать поле, относящееся к порядку байтов. Итак, теперь вы можете просто использовать эту команду, чтобы узнать это:$ lscpu | grep -i byte Byte Order: Little Endian
Это было подтверждено в Ubuntu 12.10 и CentOS 6. Так что я готов предположить, что большинство ядер Linux 3.0+ теперь предлагают это.
В Debian / В системах Ubuntu вы также можете использовать эту команду, не зная, когда она стала доступной:
$ dpkg-architecture | grep -i end DEB_BUILD_ARCH_ENDIAN=little DEB_HOST_ARCH_ENDIAN=little
Ссылки
Если вы используете Linux недавно (почти все после 2012 года) , то lscpu
теперь содержит следующую информацию:
$ lscpu | grep Endian
Byte Order: Little Endian
Это было добавлено в lscpu
] в версии 2.19, которая находится в Fedora> = 17, CentOS> = 6.0, Ubuntu> = 12.04.
Обратите внимание, что я нашел этот ответ из этого потрясающего ответа на Unix.SE . В этом ответе много важной информации, этот пост - всего лишь его резюме.
Вы можете использовать формат файла ELF, чтобы определить порядок байтов в вашей системе. Например, выведите первые шесть байтов произвольного файла ELF в шестнадцатеричном формате:
xxd -c 1 -l 6 / bin / ls
0000000: 7f.
0000001: 45 E
0000002: 4c L
0000003: 46 п.
0000004: 02.
0000005: 01.
Если последняя строка (шестеричный байт) - 01, в соответствии с форматом ELF , 01 будет прямым порядком байтов, а 02 - прямым порядком байтов.
Если у вас нет xxd
на вашем ящике (и у вас есть busybox), попробуйте следующее:
hexdump -s 5 -n 1 -C / bin / busybox
Немного другое требование: мне нужен такой тест в сценарии конфигурации сборки программы, чтобы определить, является ли целевая машина компиляции битовой или прямой порядком байтов, без выполнения код . Скрипт должен поместить #define HAVE_LITTLE_ENDIAN 1
в заголовок config.h
, иначе #define HAVE_LITTLE_ENDIAN 0
.
Целевая машина компиляции может отличаться с машины сборки, поскольку мы можем выполнять кросс-компиляцию, что также объясняет, почему тест не должен пытаться выполнить какой-либо скомпилированный код. Не может быть и речи о маленькой программе на языке C с оператором printf
, выдающим ответ.
Возможное решение состоит в следующем. Мы генерируем файл с именем conftest.c
, который содержит следующее:
#define USPELL(C0, C1, C2, C3) \
((unsigned) C0 << 24 | \
(unsigned) C1 << 16 | \
(unsigned) C2 << 8 | (unsigned) C3)
unsigned x[6] = {
0,
USPELL('L', 'I', 'S', 'P'),
USPELL('U', 'N', 'I', 'X'),
USPELL('C', 'O', 'R', 'E'),
USPELL('D', 'W', 'I', 'M'),
0
};
Теперь мы компилируем это в conftest.o
, используя:
$ /path/to/cross-compiling/cc conftest.c -c
Затем мы запускаем:
$ strings conftest.o
PSILXINUEROCMIWD
Если строка PSILXINUEROCMIWD
, цель - прямой порядок байтов. Если встречается строка LISPUNIXCOREDWIM
, она имеет прямой порядок байтов. Если ни одна строка не встречается или, что еще более удивительно, появляются обе, значит, тест не удался.
Этот подход работает, потому что вычисленные в программе константы "fourcc" имеют машинно-независимые значения, обозначающие одни и те же целые числа независимо от порядка байтов. Их представление хранения в объектном файле соответствует порядку байтов целевой системы, и это видно через символьное представление в строках
.
Два нулевых защитных слова гарантируют, что строка изолирована. Это не обязательно, но это гарантирует, что искомая строка не будет встроена в какую-либо другую строку, а это означает, что strings
выведут ее в отдельной строке.
P.S. макрос USPELL
не помещает в скобки вставку аргументов, потому что он создан для этой конкретной цели, а не для повторного использования.
вот решение, которое включает в себя полное неправильное использование кодов выхода оболочки posix. :
gawk/mawk/mawk2/nawk 'BEGIN { # system() returns 1
# if little-endian.
# to check BE, change that -c 2 to -c 5
print system("
exit \140<<<\47\47 gnu-od | grep -c 2\140") }'
\47 = одинарная кавычка ascii, а \140 - это гравюра ascii
- , за исключением gnu-gawk -S режима песочницы, который отключает system( )
что это делает выполнить это —>
exit ` <<<'' god | grep -c 2 `
внутри оболочки posix sh, в основном запрашивая gnu-od, чтобы показать вам 2-байтовые восьмеричные числа по умолчанию из одного символа \n (d=10)
.
в системах с прямым порядком байтов он отображается как 000012. Но в системах с обратным порядком байтов дополнительный байт заполнения заставляет gnu-od повышать восьмеричные числа. десятичное число 10 * 256 = 2560 = 5x8x8x8, поэтому результирующее 2-байтовое восьмеричное число равно 005000. Затем используйте функцию счетчика grep, чтобы найти либо 2, либо 5.
Коды выхода должны быть такими, что 0 означает успех, а каждое большее число означает какую-то ошибку. но поскольку счетчик grep уже помог нам инвертировать это, возвращаемый «код выхода» системной команды уже имеет логическое значение awk true (1) и false (0).
Мне немного не нравится ответ, который опирается на формат ELF, так как он не везде используется (это могут быть скрипты, или другой binfmt, или даже система cygwin). Вот относительно переносимый, который опирается только на POSIX и шестнадцатеричный дамп
(поэтому совместим с busybox, если вы стремитесь к совместимости с POSIX, вместо этого следует использовать awk
):
if test `printf '\0\1' | hexdump -e '/2 "%04x"'` -eq 0100
then
echo little
else
echo big
fi
Также проверьте средний -endian:
case `printf '\0\1\2\3' | hexdump -e '/4 "%08x"'` in
03020100) echo little;;
00010203) echo big;;
01000302) echo mid-big;;
02030001) echo mid-little;; # these two might be swapped, adjust accordingly
*) echo unknown endianness
esac
Как это работает? Printf печатает байт за байтом в следующем порядке: 00 01
.
Шестнадцатеричный дамп был адаптирован из здесь.
/4
указывает применить форматирование сразу к группам из 4 байтов. "%08x"
— это выходной формат (8 шестнадцатеричных символов с ведущим 0). Идея здесь в том, что он будет читать число в его родном порядке байтов и отображать его в «удобочитаемом» формате с прямым порядком байтов. X -> Y endian — это тот же обмен, что и Y -> X. Таким образом, big -> native выполняется здесь с помощью шестнадцатеричного дампа, хотя предполагается, что native -> big.
Если у кого-то есть математическое объяснение этому, мне было бы любопытно, кстати. Замена два раза эквивалентна тождеству.
I
(глаз), а не нижний регистрl
(эль) между прочим. – Paused until further notice. 23 July 2010 в 20:13