Fare l'Xor di due stringhe in C

Ciao a tutti.
Come da titolo avrei bisogno di fare un Xor tra una chiave Hardware (letta da un device DS2431) ed una stringa presente in un array di char.
Il risultato dovrà essere messo in un'altro array che poi analizzerò.
Ho due problemi:
1-Devo convertire l'array di caratteri
char caratteri[14]
nel corrispettivo array di byte
byte confronta[7]
2-Il codice della chiave Hw viene salvato in un array di byte
byte chiave[7];
e deve essere poi fatto Xor con confronta e il risultato salvato in confronta.
Come posso fare???
grazie per l'aiuto

  1. Lo xor si fa semplicemente con l'operatore ^

1 .
a.Un byte è semplicemente un unsigned char
Se non ci sono valori sopra a 127, il valore di un char (che ha segno) è uguale ad un byte
Anzi, un valore come 128 sempre è 10000000 in binario, l'unica differenza è che byte non considera quel bit numero 8 come segno.
b.Oltre a questo, hai un array di 14 elementi char e un array di 7 elementi byte.
Forse è utile avere più informazioni su quello che devi fare, farci capire da dove leggi questi dati e a cosa servono. Perchè "Devo convertire l'array di caratteri in nel corrispettivo array di byte"
non ha molto senso a meno che non ci sia una codifica di cui non menzioni

Il discorso è che scrivo nel monitor seriale un codice alfanumerico di 14 cifre e lo salvo in un array char lungo 14.
La chiave hardware è composta da 14 'caratteri' alfanumerici, ma leggendola leggo 7 coppie esadecimali (es 2D C5 2A 14 29 00 00), cioè 7 byte.
Quello che voglio fare è prendere la chiave hw letta, prendere quello scritto in seriale e fare l'Xor tra i due.
Questo non ha uno scopo ben preciso, ma volevo un po' 'giocare' (passatemi il termine, più che altro capire...) come muoversi con i numeri.
Poi forse ho sbagliato l'approcio...

Esiste la strtol() per convertire anche esadecimali ma dovresti iniziare la stringa con 0x e poi farlo a coppie perchè tutta intera 0x2DC52A14290000 è più grande di un long

Perciò devi convertire le singole cifre/lettere in valore decimale, e devi fare il tutto a coppie di carattere (ciclo for con incremento di 2).
Devi tu farti il calcolo, x esempio, 2D sono '2' e 'D' dentro l'array a posizione 0 e 1
Devi avere una variabile byte accumulatore. Se la lettera è tra '0' e '9' togli 48 perchè '1'=ascii 49 e -48 ottieni 1, se la lettera è tra 'A' e 'F' togli 55 'A'=ascii 65 - 55 = 10
(2×16) + (13)=32+13=45 come byte

Può anche fare XOR tra valori esadecimali di due caratteri:
0x2D ^ 0xB2
0xC5 ^ 0x4D
...

Io in genere utilizzo lo xor quando devo leggere una serie di ingressi, tipo la lettura diretta di una porta di Arduino o un byte in arrivo da un pcf8574.
Con poche operazione logiche aggiuntive riesco a testare i fronti di variazione degli 8 bit contemporaneamente, a tutto vantaggio di velocità

Grazie Datman,lo tengo in considerazione...
Faccio un'altra domanda: facendo lo shift destro con l'operatore >>, vengono immessi a sinistra (MSB) tanti zeri quante sono le posizioni da shiftare, e i bit a destra vengono persi.
Io vorrei invece che i bit in uscita rientrino nel MSB e scorra in maniera circolare.
Io programmavo con l'assembler e mi ricordo che si poteva fare uno shift con carry, in modo che il bit in uscita rientrava nel MSB.
E' possibile farlo anche con arduino?
Se si quale comando è?
Se no, quale soluzione adottare?
Grazie.

Qui trovi una discussione su come integrare l'assembly nel C:
https://forum.arduino.cc/t/assembly-su-arduino-inline-assembly/70373/16
La funzione in assembly, naturalmente, dovrà ricevere non la variabile ma il suo indirizzo.

In C, comunque, puoi fare una cosa del genere:

byte A = 0b10010010;
byte B = (A>>1) + ((A    &1)<<7);
byte C = (A>>2) + ((A &0b11)<<6);
byte D = (A>>3) + ((A&0b111)<<5);

Più in generale, con la maschera = (1<<n)-1:
byte E = (A>>n)  +  ((A& ((1<<n)-1)) << (8-n));

Puoi anche scrivere una funzione:
byte rotBit (byte A, byte n)
  {
  byte B = (A>>n)  +  ((A& ((1<<n)-1)) << (8-n));
  return B;
  }

In merito mi permetto di suggerire QUESTO ottimo libro (dal prezzo più che abbordabile).

Guglielmo

2 Likes

Grazie Datman, è proprio quello che fa per me...
Non ci ero arrivato alla funzione...
Questo per spostare a destra, se devo spostare a sinistra cosa cambia?

Datman, correggimi se sbaglio...
Per ruotare a sx ho scritto come segue:

byte E = (A<<n)  +  ((A& ((128<<n) >> (8-n));

Può andare?
Quindi scriverei le funzioni così

byte rotBit_dx (byte A, byte n)
  {
  byte B = (A>>n)  +  ((A& ((1<<n)-1)) << (8-n));
  return B;
  }
byte rotBit_sx (byte A, byte n)
  {
  byte B = (A<<n)  +  ((A& ((128>>n) >>(8-n));
  return B;
  }

 
Resta da fare l' OR :wink: