CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[help] programmation bas niveau (creation de packets)

dark_drow
dark_drow
Niveau 15
17 mai 2020 à 01:25:11

Salut,

J'ai une mission dans laquelle je dois créer et envoyer des packets "custom" sur un réseau mais je suis un peu à la rue sur la 'programmation binaire' (moi qui fait du web depuis 7ans..).

Histoire de mettre un peu de piment dans la sauce, le packet n'a pas un format fixé (comme TCP), il y a des bits de 'présence' : si bit=1, alors les X prochains bits indiquent telle info, sinon rien, champs suivant (ça permet d'économiser de la bande passante, mais pas mes cheveux)

Avez vous des conseils ou un exemple d’implémentation pour m'aider à démarrer (Java) ?

Le début de mon packet est comme ça (et la spec fait 300 pages... :help:)

4 bit de version | 1 bit de présence encodage | 2 bit (encodage) | 1 bit de présence destinataire | destinataire sur 448 bit max | ...

Le tout doit évidement être en plus "paddé" pour être un multiple de 8
Merci d'avance, je prends toute l'aide disponible :o))

Message édité le 17 mai 2020 à 01:26:16 par dark_drow
[Black_Spirit]
[Black_Spirit]
Niveau 19
17 mai 2020 à 13:19:21

Regarde la lib python Scapy, ça peut te donner des idées d'implémentation.

https://scapy.readthedocs.io/en/latest/usage.html

lokilok
lokilok
Niveau 16
17 mai 2020 à 14:36:00

Je comprends pas trop la question. Mais globalement tu as juste à isoler le premier octet (si tu récupères un tableau d'octets bah tu prends juste le premier), et après tu lui applique des masques pour récupérer les informations que tu veux.

Genre (en supposant que data est un tableau d'octets):
- "data[0] & 0b1" te donnes la valeur du bit "présence destinataire".
- "(data[0] & (0b11 << 1)) >> 1" te donne la valeur des deux bits d'encodage, etc etc.

En gros & c'est l'opérateur & bit à bit, ça applique l'opérateur & sur chaque bit des deux opérandes et retourne le résultat.
L'opérateur << et >> sont de bit shift, ça décale tous les bits vers la gauche ou la droite du nombre indiqué.

Du coup tu utilises l'opérateur & pour appliquer un masque et isoler les bits qui t'intéresse, puis tu les décale le plus à droite (enfin là où les bits ont le poids le plus faible) pour qu'ils aient la valeur à laquelle tu t'attends. La partie décalage de bits est pas obligatoire mais plus facile pour raisonner sur ta valeur.

Après il y a un truc à savoir, c'est que certaines machines sont en little endian (octet de poids faible en premier) et d'autres en big endian (octet de poids fort en premier). En général quand tu envoies un nombre tu le convertis dans une endianness commune pour tout le monde (celle du network) puis quand tu le lis tu le reconvertis dans l'endianness de ta machine (host). En C il y a les fonction hton / ntoh (host to network / network to host). Mais c'est que nécessaire si tu manipules des nombres de plusieurs octets.

Message édité le 17 mai 2020 à 14:39:45 par lokilok
dark_drow
dark_drow
Niveau 15
17 mai 2020 à 17:58:55

@lokilok oui a la limite le décodage me pose peut être moins de problème (quoi que..)

data[0] & 0b1" te donnes la valeur du bit "présence destinataire"

Je veux bien un petit cours pour les nuls ^^' mon raisonnement c'est que 0b1 = 10110001 donc mon opération sera data[0] & 10110001 = X0XX000X (X=1 si le bit correspondant dans data est à 1, sinon 0 - c'est ça qu'on appelle un bitmask ?) En quoi ça m'aide de récupérer ces bits là ?

L'autre problème ici c'est que contrairement à un protocole "classique", la position des les bits est dynamique et ils ne sont pas "alignés" et c'est vraiment la misère.
Un truc plus classique ça serait:
2bit pour la version | 2 bit encodage | 448 bit destinataire
et du coup effectivement je pense qu'avec des masques pour décoder et des opérations binaires pour encoder c'est a peu près accessible.

Là mes informations se retrouvent à une position complètement dynamique et j'ai du mal a voir comment manipuler les bits à un niveau si précis. Dans mon cas, le 6e bit peut être le bit de présence du destinataire, ou bien le 1er bit d'encodage si le 5e bit est à 1. L'effet indésirable étant que quand j'encode un entier ou un char, il peut se retrouver "à cheval" sur 2 octets

Après vu ta réponse et ce que je peux dénicher sur SOF, j'ai l'impression que mon seul choix sera d'avoir un algo avec 2 compteurs : un compteur de l'octet actuel et un compteur du bit actuel et faire mes décalages en fonction de ça ? ça me parait être super risqué en terme de bug/debug :/

Message édité le 17 mai 2020 à 18:03:42 par dark_drow
lokilok
lokilok
Niveau 16
17 mai 2020 à 20:57:48

Je veux bien un petit cours pour les nuls ^^' mon raisonnement c'est que 0b1 = 10110001

0b1 = 00000001. 0b c'est juste le préfixe pour écrire du binaire, comme 0x pour de l'hexa. Pour le reste le raisonnement est bon.

Et du coup pour l'écriture (en supposant que de base tu as un data qui ne contient que des 0) :
- "data[0] |= 0b1" set la valeur du bit "présence destinataire" à 1.
- "data[0] |= (0b10 << 1)" set la valeur des deux bits d'encodage à 2.

Là mes informations se retrouvent à une position complètement dynamique et j'ai du mal a voir comment manipuler les bits à un niveau si précis. Dans mon cas, le 6e bit peut être le bit de présence du destinataire, ou bien le 1er bit d'encodage si le 5e bit est à 1.

Si tu fais une fonction pour accéder au bit numéro X (ou au bit X de l'octet Y) dans ton tableau ça serait peut-être plus simple après pour faire tes diverses opérations.

L'effet indésirable étant que quand j'encode un entier ou un char, il peut se retrouver "à cheval" sur 2 octets

Ah ouais ça c'est plus chiant à gérer. Si la performance c'est pas un point critique de ton programme je dirais que réaligner toi-même les nombres en copiant les bits dans un nouveau tableau c'est peut-être la solution la plus simple. Je sais pas trop j'ai jamais eu à faire ça.

Après vu ta réponse et ce que je peux dénicher sur SOF, j'ai l'impression que mon seul choix sera d'avoir un algo avec 2 compteurs : un compteur de l'octet actuel et un compteur du bit actuel et faire mes décalages en fonction de ça ? ça me parait être super risqué en terme de bug/debug :/

Tu peux uniquement avoir un compteur de bits, sachant que tu peux déduire l'octet auquel se trouve ce bit et le décalage nécessaire avec des divisions / modulos. Avoir un seul compteur à gérer c'est plus simple que d'en gérer deux qui doivent être synchronisés.

Message édité le 17 mai 2020 à 21:00:54 par lokilok
dark_drow
dark_drow
Niveau 15
18 mai 2020 à 14:22:08

merci pour tes conseils :)

Sous forums
  • Aide à l'achat Mac
  • Internet
  • Macintosh
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Steam Deck
  • Hardware
La vidéo du moment