16進制字符串轉QByteArray
QByteArray HexStringToByteArray(QString HexString) { bool ok; QByteArray ret; HexString = HexString.trimmed(); HexString = HexString.simplified(); QStringList sl; for(int i=0; i<HexString.length()/2; i++) { sl.append(HexString.mid(i*2, 2)); } foreach (QString s, sl) { if(!s.isEmpty()) { char c = s.toInt(&ok,16)&0xFF; if(ok){ ret.append(c); }else{ qDebug()<<QString::fromLocal8Bit("非法的16進制字符:")<<s; } } } qDebug()<<ret; return ret; } QByteArray baRsuData = HexStringToByteArray("FFFF58B40C120AFE01000000090000891700000000B9F3D6DDB8DFCBD91611520113282202000961892014112420441124B9F3414B44313538000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001350000000000000000000000000000000000010000000000AA290014514407A15D42BCFE00010300000000000000000067DE7901B9F3414B443135380000000015000000C1FF");
QString(baRecv.toHex().toUpper())
大端小端字節序互轉
定義變量 unsigned long long a=0x1122334455667788
變量a是一個64位的無符號整數,共需要8個字節來存儲,那么在兩種模式下是如何存儲的呢?
||--1--||--2--||--3--||--4--||--5--||--6--||--7--||--8--|| 地址
|| 11 || 22 || 33 || 44 || 55 || 66 || 77 || 88 || 大端模式
|| 88 || 77 || 66 || 55 || 44 || 33 || 22 || 11 || 小端模式
在我們日常使用的x86架構的計算機中(其他類別的可能會采用大端模式或可配置模式,可以通過查閱資料或者用下文的代碼進行測試),都是使用的小端模式,而網絡字節序是大端模式的。
文件存儲中的模式
文件的存儲一般都是以字節來進行操作的,因此,在文件中以什么樣的字節序需要程序的編寫者加以注意。比方說下面的程序:
int a=0x11223344; FILE *fp; fp=fopen("test","wb"); fwrite(&a,sizeof(a),1,fp); fclose(fp);
用十六進制編輯器打開文件之后,我們會發現文件的內容是44332211。原因很簡單,fwrite函數直接把內存中的內容按順序寫入了文件,因此內存中是小端模式存儲的,所以寫入文件也是小端模式。
優缺點
大端模式,由於符號位和數值的高位存在地址的低位,會優先被讀到,更容易先確定數據的重要信息。
小端模式,在進行類型轉換的時候不需要調整數據。如int強制轉換到char,計算機不需要做任何調整,直接讀取int的第一個字節即可。
Qt中大端小端的轉換
Qt中<QtEndian>包含了大端小端轉換的幾個函數
T qFromBigEndian(const uchar * src) T qFromBigEndian(T src) T qFromLittleEndian(const uchar * src) T qFromLittleEndian(T src) void qToBigEndian(T src, uchar * dest) T qToBigEndian(T src) void qToLittleEndian(T src, uchar * dest) T qToLittleEndian(T src)
下面對幾個函數進行說明
union{ int a; char b[4]; }test1,test2; test1.a=0x61626364; test2.a=qFromBigEndian(test1.a); qDebug()<<test1.b[0]<<test1.b[1]<<test1.b[2]<<test1.b[3]; qDebug()<<test2.b[0]<<test2.b[1]<<test2.b[2]<<test2.b[3];
對於qFromBigEndian()函數,它會判斷執行程序的主機的字節序,如果是大端模式的計算機,那么只是讀取數據,不進行轉換,如果是小端模式的計算機,那么則進行轉換。
因此我在本機(小端模式)上的的執行結果是:
d c b a
a b c d
可以看出,它將數據進行了轉換。
對於qFromLittleEndian()函數,和前者類似。對於大端模式的計算機進行轉換,對於小端模式的計算機只是讀取數據。
union{ int a; char b[4]; }test1,test2; test1.a=0x61626364; test2.a=qFromLittleEndian(test1.a); qToBigEndian(test1.a,(uchar*)test2.b); qDebug()<<test1.b[0]<<test1.b[1]<<test1.b[2]<<test1.b[3]; qDebug()<<test2.b[0]<<test2.b[1]<<test2.b[2]<<test2.b[3];
對於qToBigEndian()函數,也有着上面的規則,對於小端模式的計算機進行轉換,對於大端模式的計算機只進行讀取。
因此,本機(小端模式)的執行結果是:
d c b a
a b c d
對於qToLittleEndian()函數,只對大端模式的計算機進行轉換。
需要注意的是,Qt中的模板T只針對有符號和無符號的整型,對於浮點型(一般也不會用到),需要進行強制類型轉換。
原文:https://blog.csdn.net/usownh/article/details/42614185