2014-12-19 17 views
5

sto leggendo attraverso una libreria (github.com/adduc/phpmodbus) e c'è questa funzione per la conversione di numero intero a stringa little-endian o big-endian di byte:Questa conversione di endianness è corretta?

private static function endianness($value, $endianness = 0) { 
    if ($endianness == 0) 
     return 
       self::iecBYTE(($value >> 8) & 0x000000FF) . 
       self::iecBYTE(($value & 0x000000FF)) . 
       self::iecBYTE(($value >> 24) & 0x000000FF) . 
       self::iecBYTE(($value >> 16) & 0x000000FF); 
    else 
     return 
       self::iecBYTE(($value >> 24) & 0x000000FF) . 
       self::iecBYTE(($value >> 16) & 0x000000FF) . 
       self::iecBYTE(($value >> 8) & 0x000000FF) . 
       self::iecBYTE(($value & 0x000000FF)); 
} 

La funzione iecBYTE è solo chr($value & 0xFF).

Ora forse sono spessa, ma la stringa little-endian sembra sbagliata.
Ad esempio, con 0xAABBCCDD, otterresti {CC}{DD}{AA}{BB}.

Ho persino cercato su Wikipedia. Non dovrebbe essere {DD}{CC}{BB}{AA}?

Il codice funziona, ma questo mi confonde davvero. È giusto e lo capisco in modo errato?

+1

Cosa intendi con? Potrebbe forse essere "funzionante" ma semplicemente non funziona correttamente? – imtheman

+0

Forse ho frainteso ciò che sta facendo il metodo, non sono sicuro. Il metodo è usato parecchio nella libreria e funziona correttamente. – MightyPork

risposta

0

Dopo aver guardato il IECType.php, ho notato che è la conversione tipi PHP ai tipi IEC 1131. Little endian sta memorizzando prima i byte meno significativi. Ciò che descrivendo mi farebbe pensare che il sistema stia usando indirizzi a 16 bit.

Se si guarda lo wiki per Endianess a cui si fa riferimento nei commenti sopra la funzione endianess, verrà visualizzata una sezione in Little-endian denominata dimensione elemento atomico a 16 bit. Un indirizzo contiene due byte (CCDD) e (AABB). L'indirizzo che detiene il (CCDD) è meno significativo quindi verrà elencato per primo.

Se si lavorava in un sistema a 8 bit, ogni byte sarebbe stato ordinato (DDCCBBAA) perché ci sarebbe stato un byte per indirizzo.

Wiki descrive ciò che si sta vedendo nella funzione di endianess.

 
address1| address2 
16-bits | 16-bits 
CCDD | AABB 
0

Sei corretto. La funzione non è corretta, sebbene sia vicina. Sembra che tu debba solo scambiare alcune conversioni. Logicamente la conversione little-endian ($ endianness == 0) è solo l'inverso della conversione big-endian ($ endianness! = 0).

private static function endianness($value, $endianness = 0) { 
    if ($endianness == 0) //little-endian 
     return 
       self::iecBYTE($value & 0x000000FF) . 
       self::iecBYTE(($value >> 8) & 0x000000FF) . 
       self::iecBYTE(($value >> 16) & 0x000000FF) . 
       self::iecBYTE(($value >> 24) & 0x000000FF); 
    else //big-endian 
     return 
       self::iecBYTE(($value >> 24) & 0x000000FF) . 
       self::iecBYTE(($value >> 16) & 0x000000FF) . 
       self::iecBYTE(($value >> 8) & 0x000000FF) . 
       self::iecBYTE(($value & 0x000000FF)); 
}