﻿# Функции класса ntohl/htonl и работа с 64\-битными значениями

Как известно, порядок байт в целых числах, представление которых занимает более одного байта, может быть для различных компьютеров неодинаковым\. Есть вычислительные системы, в которых старший байт числа имеет меньший адрес, чем младший байт \(big\-endian byte order\), а есть вычислительные системы, в которых старший байт числа имеет больший адрес, чем младший байт \(little\-endian byte order\)\. При передаче целой числовой информации от машины, имеющей один порядок байт, к машине с другим порядком байт мы можем неправильно истолковать принятую информацию\. Для того чтобы этого не произошло, было введено понятие сетевого порядка байт, то есть порядка байт, в котором должна представляться целая числовая информация в процессе передачи ее по сети \(был выбран big\-endian byte order\)\. Целые числовые данные из представления, принятого на компьютере\-отправителе, переводятся пользовательским процессом в сетевой порядок байт, в таком виде путешествуют по сети и переводятся в нужный порядок байт на машине\-получателе процессом, которому они предназначены\. Для перевода целых чисел из машинного представления в сетевое представление и обратно, используются четыре функции: htons\(\), htonl\(\), ntohs\(\), ntohl\(\)\.

Описание функций:

* Функция htonl осуществляет перевод целого числа из порядка байт, принятого на компьютере, в сетевой порядок байт\.
* Функция htons осуществляет перевод целого короткого числа из порядка байт, принятого на компьютере, в сетевой порядок байт\.
* Функция ntohl осуществляет перевод целого числа из сетевого порядка байт в порядок байт, принятый на компьютере\.
* Функция ntohs осуществляет перевод целого короткого числа из сетевого порядка байт в порядок байт, принятый на компьютере\.

Перечисленные функции работают с 16\-битными и 32\-битными значениями\. С приходом 64\-битных систем повысилась потребность в функциях, работающих с 64\-битнымим величинами\. В ряде систем для работы с 64\-битными значениями появились функции ntohll\(\) и htonll\(\)\. Но в ряде систем этих функций нет\. В этом случае вы можете сами реализовать необходимую функциональность\.

В обсуждении "[64 bit ntohl\(\) in C\+\+ ?](https://stackoverflow.com/questions/809902/64-bit-ntohl-in-c)" вы можете найти ряд решений по преобразованию 64\-битных величин\. Приведем одно из них\.

```cpp
#define TYP_INIT 0 
#define TYP_SMLE 1 
#define TYP_BIGE 2 
 
unsigned long long htonll(unsigned long long src) { 
  static int typ = TYP_INIT; 
  unsigned char c; 
  union { 
    unsigned long long ull; 
    unsigned char c[8]; 
  } x; 
  if (typ == TYP_INIT) { 
    x.ull = 0x01; 
    typ = (x.c[7] == 0x01ULL) ? TYP_BIGE : TYP_SMLE; 
  } 
  if (typ == TYP_BIGE) 
    return src; 
  x.ull = src; 
  c = x.c[0]; x.c[0] = x.c[7]; x.c[7] = c; 
  c = x.c[1]; x.c[1] = x.c[6]; x.c[6] = c; 
  c = x.c[2]; x.c[2] = x.c[5]; x.c[5] = c; 
  c = x.c[3]; x.c[3] = x.c[4]; x.c[4] = c; 
  return x.ull; 
}
```

## Библиографический список

1. Juan Carlos Cobas\. [Basic concepts on Endianness](https://www.codeproject.com/articles/4804/basic-concepts-on-endianness)\.
1. Question on Stackoverflow\.com\. [64 bit ntohl\(\) in C\+\+?](https://stackoverflow.com/questions/809902/64-bit-ntohl-in-c)
1. Wikipedia\. [Endianness](https://en.wikipedia.org/wiki/Endianness)\.