6
votes

Comment modifier l'ordre d'octet de 128 bits

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 */

c gcc

1 commentaires

Ce n'est pas mauvais, mais j'ajouterais un point-virgule après octet [i] . ;)


6 Réponses :


4
votes

Si vous pouvez facilement obtenir le haut et le faible __ int64 s, alors vous pouvez inverser et échanger. Sinon, vous devrez probablement regarder chaque octet individuellement.


1 commentaires

Utilisation de GCC __ BUSETIN_BSWAP64 faciliterait cela aussi.



0
votes

pas si efficace mais; xxx


0 commentaires

3
votes
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

0 commentaires

1
votes

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. XXX

Ensuite, vous avez besoin d'une expression de monstre xxx

où vous " d doivent remplacer le xx par les valeurs correspondant à la valeur de décalage pour cet octet.

MAINTENANT Votre valeur Swewed est simplement Swed (n) .Je Et un bon compilateur devrait savoir par lui-même quelles instructions d'assembleur à utiliser pour tout cela.


0 commentaires

3
votes

Depuis que vous avez explicitement dit x86_64, vous pouvez lancer vers __ m128i et utiliser l'instruction PSHUFB ou _mm_shauffe_epi8 , respectivement. Prenez soin d'aligner correctement vos données (bien que le compilateur doit déjà aligner un __ int128 correctement) afin que le compilateur puisse utiliser MOVDQA (GCC est plutôt bon à cela, si possible, le cas échéant). Vous devez inclure pour _mm_shauffe_epi8 .

Notez que vous avez aura besoin de la mise en œuvre de la relèvement (éventuellement lente), car certains processeurs AMD64 très précoce d'environ 2003-2004 n'ont pas de soutien SSE3.


0 commentaires

0
votes

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: xxx pré>

si vous utilisez c ++, remplacez le style C Conts ci-dessus avec Reterpret_cast Code>. P>

Selon Godbolt , le Swap code> est compilé vers cette assemblée pour CLANG 12, -O3: P>

mov     rax, rsi
bswap   rdi
bswap   rax
mov     rdx, rdi
ret


0 commentaires