J'ai une gamme de caractères non signés qui représente un numéro de 128 bits dans l'ordre des octets de réseau. Comment puis-je continuer à convertir cela en ordre d'octet d'hôte efficacement (dans ce cas x86_64)?
Il ne semble pas y avoir de macros disponibles dans Endian.h et ma tentative de convertir les 64 bits supérieurs et plus bas 64 bits de manière indépendante n'a pas fonctionné. La seule méthode que j'ai constatée que cela fonctionne certainement est une boucle comme si: p>
union { unsigned char b[MD5_DIGEST_LENGTH]; uint64_t d[2]; unsigned __int128 q; } digest; MD5((const unsigned char *)str, length, digest.b); uint64_t tmp = digest.d[0]; digest.d[0] = be64toh(digest.d[1]); digest.d[1] = be64toh(tmp); /* digest.q is now in native byte order */
6 Réponses :
Si vous pouvez facilement obtenir le haut et le faible __ int64 code> s, alors vous pouvez inverser et échanger. Sinon, vous devrez probablement regarder chaque octet individuellement. P>
Utilisation de GCC __ BUSETIN_BSWAP64 CODE> faciliterait cela aussi.
pas si efficace mais;
union _128_as_64 { unsigned __int128 v; unsigned __int64 q[2]; } u1, u2; u1.v = num; u2.q[1] = betoh64(u1.q[0]); u2.q[0] = betoh64(u1.q[1]); // do something with u2.v
Si vous connaissez le modèle de réshidification des octets, vous pouvez utiliser un littéral composé pour cela. D'abord, je déclarais un type syndical, juste pour éviter une frappe de taper. Ensuite, vous avez besoin d'une expression de monstre p> où vous " d doivent remplacer le MAINTENANT Votre valeur Swewed est simplement xx code> par les valeurs correspondant à la valeur de décalage pour cet octet. p>
Swed (n) .Je code > Et un bon compilateur devrait savoir par lui-même quelles instructions d'assembleur à utiliser pour tout cela. p> p>
Depuis que vous avez explicitement dit x86_64, vous pouvez lancer vers Notez que vous avez __ m128i code> et utiliser l'instruction PSHUFB ou
_mm_shauffe_epi8 code>
, respectivement. Prenez soin d'aligner correctement vos données (bien que le compilateur doit déjà aligner un __ int128 code> correctement) afin que le compilateur puisse utiliser MOVDQA (GCC est plutôt bon à cela, si possible, le cas échéant).
Vous devez inclure
_mm_shauffe_epi8 code>. P>
Voici une implémentation en fonction de la suggestion de Joshua d'échanger les octets de blocs de 64 bits individuellement, puis d'échanger les blocs de 64 bits: si vous utilisez c ++, remplacez le style C Conts ci-dessus avec Selon Godbolt , le Reterpret_cast Code>. P>
Swap code> est compilé vers cette assemblée pour CLANG 12, -O3: P>
mov rax, rsi
bswap rdi
bswap rax
mov rdx, rdi
ret
Ce n'est pas mauvais, mais j'ajouterais un point-virgule après
octet [i] code>. ;)