197 votes

C# int vers byte[]

Je dois convertir un int à un byte[] Une façon de le faire est d'utiliser BitConverter.GetBytes() . Mais je ne suis pas sûr que cela corresponde à la spécification suivante :

Un entier signé XDR est une donnée de 32 bits qui encode un entier en l'intervalle [-2147483648,2147483647]. Le nombre entier est représenté en notation du complément à deux. Les octets les plus et les moins significatifs sont 0 et 3, respectivement. Les nombres entiers sont déclarés comme suit :

Source : RFC1014 3.2

Comment puis-je faire une transformation de int en byte qui satisfasse la spécification ci-dessus ?

0 votes

C'est une bonne question.

245voto

paracycle Points 4021

La RFC essaie simplement de dire qu'un entier signé est un entier normal de 4 octets avec des octets ordonnés de manière big-endian.

Maintenant, vous travaillez très probablement sur une machine little-endian et BitConverter.GetBytes() vous donnera le byte[] inversé. Donc vous pourriez essayer :

int intValue;
byte[] intBytes = BitConverter.GetBytes(intValue);
Array.Reverse(intBytes);
byte[] result = intBytes;

Cependant, pour que le code soit le plus portable possible, vous pouvez procéder comme suit :

int intValue;
byte[] intBytes = BitConverter.GetBytes(intValue);
if (BitConverter.IsLittleEndian)
    Array.Reverse(intBytes);
byte[] result = intBytes;

8 votes

Ou utilisez ToArray. byte[] result = BitConverter.GetBytes(intValue).Reverse().ToArray() ;

1 votes

Pourquoi la dernière ligne byte[] result = intBytes; ? n'est pas intBytes déjà le tableau que vous voulez ?

2 votes

@derHugo C'est exact, result est redondant dans ce morceau de code. Cependant, j'ai pensé qu'il était plus pédagogique de montrer explicitement au lecteur quel était le résultat que de supposer qu'il puisse comprendre que le résultat est contenu dans une variable appelée intBytes . De plus, l'affectation est peu coûteuse puisqu'elle ne copie pas la mémoire et n'en alloue pas de nouvelle, elle ajoute simplement un nouveau nom au tableau déjà alloué. Alors pourquoi ne pas le faire ?

46voto

Maciek Points 4634

Voici une autre façon de procéder : comme nous le savons tous, 1 octet = 8x bits et un entier "normal" (int32) contient 32 bits (4 octets). Nous pouvons utiliser l'opérateur >> pour décaler les bits vers la droite (l'opérateur >> ne change pas la valeur).

int intValue = 566;

byte[] bytes = new byte[4];

bytes[0] = (byte)(intValue >> 24);
bytes[1] = (byte)(intValue >> 16);
bytes[2] = (byte)(intValue >> 8);
bytes[3] = (byte)intValue;

Console.WriteLine("{0} breaks down to : {1} {2} {3} {4}",
    intValue, bytes[0], bytes[1], bytes[2], bytes[3]);

1 votes

L'initialisateur de tableau et les fonctions xor (^) et & 0xFF sont inutiles.

6 votes

C'est big-endian, donc le MSB est stocké en premier, donc vous devez inverser vos indices.

7 votes

Peut-on ajouter un exemple d'aller dans le sens inverse ? (retour des octets vers les nombres entiers)

28voto

dtb Points 104373

BitConverter.GetBytes(int) fait presque ce que vous voulez, sauf que l'endianness est incorrect.

Vous pouvez utiliser le Adresse IPA.HostToNetwork pour permuter les octets dans la valeur entière avant d'utiliser la méthode BitConverter.GetBytes ou utilisez la méthode de Jon Skeet Classe EndianBitConverter . Les deux méthodes font la bonne chose(tm) en ce qui concerne la portabilité.

int value;
byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(value));

3voto

Marcin Deptuła Points 6449

Quand je regarde cette description, j'ai l'impression que cet entier xdr n'est qu'un entier big-endian "standard", mais qu'il est exprimé de la manière la plus obscure qui soit. Notation du complément à deux est mieux connu sous le nom de U2, et c'est ce que nous utilisons sur les processeurs d'aujourd'hui. L'ordre des octets indique qu'il s'agit d'un fichier de type big-endian la notation.
Donc, pour répondre à votre question, vous devriez inverser les éléments de votre tableau (0 <--> 3, 1 <-->2), car ils sont codés en little-endian. Juste pour être sûr, vous devriez d'abord vérifier BitConverter.IsLittleEndian pour voir sur quelle machine vous travaillez.

2voto

Eric J. Points 73338

Si vous souhaitez obtenir des informations plus générales sur les différentes méthodes de représentation des nombres, y compris le complément à deux, consultez le site :

Le complément à deux y Représentation de nombres signés sur Wikipédia

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X