全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:9844
推到 Plurk!
推到 Facebook!

CRC16 筆算和程式算的值完全不一樣 是哪一邊出問題呢?

缺席
tyw6455
一般會員


發表:7
回覆:9
積分:3
註冊:2005-06-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-10-11 16:49:05 IP:58.99.xxx.xxx 訂閱
最近因工作上的需求,必須使用CRC 所以找了一些CRC算法的資料及程式。
當把程式修改成在BCB上可以用的模式之後發現,用手算出來的CRC值
和電腦算出來的值是不同的,不知道是不是我已經踩到的地雷而不自知,
希望有人能指點一下。
工作上採用的是 CRC16 的 ModBus的多項式A001(1010 0000 0000 0001)
我用筆算了一下 0x41 過程及結果如下:

多項式:1010 0000 0000 0001
資料:0x41
0100 0001 0000 0000 0000 000
*^101 0000 0000 0000 1
----------------------------------------------
**001 0001 0000 0000 100
****^1 0100 0000 0000 001
--------------------------------------------
*****0 0101 0000 0000 1010 0
*******^101 0000 0000 0000 1
----------------------------------------------
******** 000 0000 0000 1010 100

CRC 值 -> 0000 0000 0101 0100
不過用程式算出來的值卻不是如此,算出來的值是 7F70
程式如下
[code cpp]

unsigned int __fastcall TfmCRC::ChkCRC(unsigned char *vcBuf, unsigned int viLen)
{
unsigned char cHi;
unsigned char cLo;
unsigned int i;
unsigned int iCRC;

iCRC = 0xFFFF;

for (i = 0; i < viLen; i )
{
iCRC = CalcCRC(*vcBuf, iCRC);
vcBuf ;
}

cHi = iCRC % 256;
cLo = iCRC / 256;
iCRC = (cHi << 8) | cLo;
return iCRC;
}
//---------------------------------------------------------------------------

unsigned int __fastcall TfmCRC::CalcCRC(unsigned char vcCRCBuf,unsigned int viCRC)
{
unsigned int i;
unsigned char cChk;

viCRC = viCRC ^ vcCRCBuf;
for (i = 0; i < 8; i )
{
cChk = viCRC & 1;
viCRC = viCRC >> 1;
viCRC = viCRC & 0x7FFF;
if (cChk == 1)
{
viCRC = viCRC ^ 0xA001;
}
viCRC = viCRC & 0xFFFF;
}

return viCRC;
}
//---------------------------------------------------------------------------

void __fastcall TfmCRC::btnCountClick(TObject *Sender)
{
int iLen = etData->Text.Trim().Length();
int iCRC;

AnsiString sData = "";

char cData[1] ;
iLen = 1;
cData[0] = 0x41;

sData = (AnsiString)cData[0];

/*
//0106000503E8 CRC->9975
char cData[6];
iLen = 6;
cData[0] = 0x01;
cData[1] = 0x06;
cData[2] = 0x00;
cData[3] = 0x05;
cData[4] = 0x03;
cData[5] = 0xE8;


sData = (AnsiString)cData[0] (AnsiString)cData[1] (AnsiString)cData[2]
(AnsiString)cData[3] (AnsiString)cData[4] (AnsiString)cData[5];

*/

iCRC = ChkCRC(sData.c_str(), iLen);

// iCRC = ChkCRC(etData->Text.Trim().c_str(), iLen);

etCode->Text = IntToHex(iCRC, 4);

}
//---------------------------------------------------------------------------

[/code]

一開始是怕程式編寫過程有問題,所以找到了有算出CRC值的資料來核對一下(即程式中)註解的程式
發現是OK的,又用了查表的方式讓電腦做了一次,結果電腦算的查表的結果跟電腦算的的相同的,但是跟筆算的不一樣,
於是找了一篇有資料、有CRC值、有多項式的文章用筆推算了一下
那篇資料網址:http://delphi.ktop.com.tw/board.php?cid=169&fid=963&tid=21165

推算過程
多項式:1 0001 0000 0010 0001
資料:0xD5
*1101 0101 0000 0000 0000 000
^1000 1000 0001 0000 1
-------------------------------------------------
*0101 1101 0001 0000 10
*^100 0100 0000 1000 01
--------------------------------------------------
**001 1001 0001 1000 1100
****^1 0001 0000 0010 0001
--------------------------------------------------
*****0 1000 0001 1010 1101 0
******^1000 1000 0001 0000 1
--------------------------------------------------
*******0000 1001 1011 1101 1000
CRC->1001 1011 1101 1000

推算的結果跟文章裡面的結果是OK的,推算方法跟最上面的推算方法並無不同,
所以希望有人能指正一下,我是踏了什麼地雷!

PS.下面的例子並沒有用電腦算過,中間的電腦驗證的地方並無用筆算過。
星號是為了讓算式對齊別無其他用意
編輯記錄
tyw6455 重新編輯於 2007-10-11 17:06:57, 註解 讓算式對齊‧
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-10-11 17:04:18 IP:210.66.xxx.xxx 訂閱
沒有測試, 用猜的^^

這裡需不需要轉型?
cHi = iCRC % 256;
cLo = iCRC / 256;
iCRC = (cHi << 8) | cLo;
return iCRC;
tyw6455
一般會員


發表:7
回覆:9
積分:3
註冊:2005-06-23

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-10-11 19:34:07 IP:58.99.xxx.xxx 訂閱
應該不是這的問題,因為用查表的方式做出來的答案跟程式RUN出來的結果是一樣
以下是查表的程式碼
[code cpp]

unsigned int __fastcall TfmCRC::CRC16(unsigned char *vcUpData,unsigned int viLen)
{
unsigned char cCRCHi = 0xFF;
unsigned char cCRCLo = 0xFF;
unsigned int iIndex;

while (viLen--)
{
iIndex = cCRCHi ^ *vcUpData ;
cCRCHi = cCRCLo ^ auchCRCHi[iIndex];
cCRCLo = auchCRCLo[iIndex];
}

return ((cCRCHi << 8) | cCRCLo);
}
//---------------------------------------------------------------------------


void __fastcall TfmCRC::btnCheckClick(TObject *Sender)
{
int iLen = etData->Text.Trim().Length();
int iCRC;

AnsiString sData = "";

iLen = 1;
char cData[1] ;

cData[0] = 0x41;

sData = (AnsiString)cData[0];

/*
//0106000503E8 CRC->9975
char cData[6];
iLen = 6;
cData[0] = 0x01;
cData[1] = 0x06;
cData[2] = 0x00;
cData[3] = 0x05;
cData[4] = 0x03;
cData[5] = 0xE8;

sData = (AnsiString)cData[0] (AnsiString)cData[1] (AnsiString)cData[2]
(AnsiString)cData[3] (AnsiString)cData[4] (AnsiString)cData[5];
*/




iCRC = CRC16(sData.c_str(), iLen);

// iCRC = ChkCRC(etData->Text.Trim().c_str(), iLen);

etCodeC->Text = IntToHex(iCRC, 4);

}

unsigned char auchCRCHi[]=
{
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
};

unsigned char auchCRCLo[] =
{
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
0x43, 0x83, 0x41, 0x81, 0x80, 0x40
};

[/code]

再不然就是整個程式的演算是錯誤的
這個要再試試了

===================引 用 jow 文 章===================
沒有測試, 用猜的^^

這裡需不需要轉型?
cHi = iCRC % 256;
cLo = iCRC / 256;
iCRC = (cHi << 8) | cLo;
return iCRC;
tyw6455
一般會員


發表:7
回覆:9
積分:3
註冊:2005-06-23

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-10-15 13:46:36 IP:58.99.xxx.xxx 訂閱
「CRC碼求餘數的除法運算規則是:做減法不產生借位,做加法不產生進位,除此以外,與二進制(模二)除法相同。」
上面這句話應該就是說需要用XOR的方式去求餘數吧,
今天早上用純粹的除法去求餘數,結果出來的值還是不對
真的看不見問題點了
純粹計算式如下:(省略商)
多項式是:0xA001
資料是:0x41

0100 0001 0000 0000 0000 0000
**-10 1000 0000 0000 01
-----------------------------------------------
*001 1000 1111 1111 110
***-1 0100 0000 0000 001
-----------------------------------------------
****0 0100 1111 1111 1010 00
********-10 1000 0000 0000 01
-----------------------------------------------
*********10 0111 1111 1001 110
**********-1 0100 0000 0000 001
------------------------------------------------
**********1 0011 1111 1001 101*<---如果左移15個位置 9FCD
***********-1010 0000 0000 0001
------------------------------------------------
************1001 1111 1001 1001<---如果左移16個位置 9F99
編輯記錄
tyw6455 重新編輯於 2007-10-15 14:12:58, 註解 無‧
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#5 引用回覆 回覆 發表時間:2007-10-15 15:18:42 IP:210.66.xxx.xxx 訂閱
0x1111 1111 1111 1111(0xFFFF)
0x0000 0000 0100 0001(0x0041)
^---------------------
0x1111 1111 1011 1110(0xFFBE),
*** Start for loop ***
>>1-------------------i==0,cChk==0
0x0111 1111 1101 1111(0x7FDF)
0x0111 1111 1111 1111(0x7FFF)
&---------------------
0x0111 1111 1101 1111(0x7FDF)
0x1111 1111 1111 1111(0xFFFF)
&---------------------i==0,cChk==0 --> & 0xFFFF
0x0111 1111 1101 1111(0x7FDF)
>>1-------------------i==1,cChk==1
0x0011 1111 1110 1111(0x3FEF)
(以下請自行推演)
[code cpp]
unsigned int __fastcall TfmCRC::ChkCRC(unsigned char *vcBuf, unsigned int viLen)
{
unsigned char cHi;
unsigned char cLo;
unsigned int i;
unsigned int iCRC;

iCRC = 0xFFFF;

AnsiString S;
ListBox1->Items->Add("iCRC==" S.sprintf("0x%4.4X", iCRC));

for (i = 0; i < viLen; i )
{
iCRC = CalcCRC(*vcBuf, iCRC);
vcBuf ;
}

ListBox1->Items->Add("iCRC==" S.sprintf("0x%4.4X", iCRC));
cHi = iCRC % 256;
cLo = iCRC / 256;
iCRC = (cHi << 8) | cLo;

ListBox1->Items->Add("iCRC==" S.sprintf("0x%4.4X", iCRC));
return iCRC;
}
[/code]

[code cpp]
unsigned int __fastcall TfmCRC::CalcCRC(unsigned char vcCRCBuf,unsigned int viCRC)
{
unsigned int i;
unsigned char cChk;

viCRC = viCRC ^ vcCRCBuf;
AnsiString S;
ListBox1->Items->Add(S.sprintf("viCRC^vcCRCBuf=0x%4.4X", viCRC));

for (i = 0; i < 8; i )
{
cChk = viCRC & 1;
ListBox1->Items->Add(S.sprintf("i=%d, cChk=%d", i, cChk));

viCRC = viCRC >> 1;
ListBox1->Items->Add(S.sprintf("0x%4.4X", viCRC));

viCRC = viCRC & 0x7FFF;
ListBox1->Items->Add(S.sprintf("0x%4.4X", viCRC));

if (cChk == 1)
{
viCRC = viCRC ^ 0xA001;
ListBox1->Items->Add(S.sprintf("0x%4.4X", viCRC));
}
viCRC = viCRC & 0xFFFF;
ListBox1->Items->Add(S.sprintf("0x%4.4X", viCRC));
}

return viCRC;
}
[/code]

電腦執行結果:
iCRC==0xFFFF
viCRC^vcCRCBuf=0xFFBE
i=0, cChk=0
0x7FDF
0x7FDF
0x7FDF
i=1, cChk=1
0x3FEF
0x3FEF
0x9FEE
0x9FEE
i=2, cChk=0
0x4FF7
0x4FF7
0x4FF7
i=3, cChk=1
0x27FB
0x27FB
0x87FA
0x87FA
i=4, cChk=0
0x43FD
0x43FD
0x43FD
i=5, cChk=1
0x21FE
0x21FE
0x81FF
0x81FF
i=6, cChk=1
0x40FF
0x40FF
0xE0FE
0xE0FE
i=7, cChk=0
0x707F
0x707F
0x707F
iCRC==0x707F
iCRC==0x7F70

僅供參考...^__^
tyw6455
一般會員


發表:7
回覆:9
積分:3
註冊:2005-06-23

發送簡訊給我
#6 引用回覆 回覆 發表時間:2007-10-15 18:33:21 IP:58.99.xxx.xxx 訂閱

謝謝JOW兄給的程式

找了不少資料,有驗證了上面不管是查表或是用算的程式都OK的
只是很納悶用紙筆按照數學的邏輯方式下去算CRC的值
一直找不出來他的多項式到等是什麼

只知道在程式裡面用的多項式(0xA001:1010 0000 0000 0001)
是由CRC-16的多項式 (X16 X15 X2 1) (0x11005)捨棄最高位數 (0x1005:1000 0000 0000 0101)
翻轉過來的

但是數學推算的多項式還是匹配不出來只能先把這個暫時先擱置了,有時間再來研究這一段
以下附上網路上部分原文:

The CRC-16 error check sequence is implemented as described in the
following paragraphs.
The message (data bits only, disregarding start/stop and optional parity
bits) is considered as one continuous binary number whose most
significant bit (MSB) is transmitted first. The message is pre-multiplied
by X16 (shifted left 16 bits), then divided by X16 X15 X2 1
expressed as a binary number (11000000000000101). The integer
quotient digits are ignored and the 16-bit remainder (initialized to all
ones at the start to avoid the case of all zeros being an accepted
message) is appended to the message (MSB first) as the two CRC check
bytes. The resulting message including CRC, when divided by the same
polynominal
(X16 X15 X2 1) at the receiver will give a zero remainder if no
errors have occurred. (The receiving unit recalculates the CRC and
compares it to the transmitted CRC). All arithmetic is performed
modulo two (no carries). An example of the CRC-16 error check for
message HEX 0207 (address 2, function 7 or a status request to slave
number 2) is given by the following example.
The device used to serialize the data for transmission will send the
conventional LSB or right-most bit of each character first. In
generating the CRC, the first bit transmitted is defined as the MSB of
the dividend. For convenience then, and since there are no carries used
in arithmetic, let’s assume while computing the CRC that the MSB is
on the right. To be consistent, the bit order of the generating
polynomial must be reversed. The MSB of the polynomial is dropped
since it affects only the quotient and not the remainder. This yields
1010 0000 0000 0001 (Hex A001). Note that this reversal of the bit
order will have no affect whatever on the interpretation or bit order of
characters external to the CRC calculations.

擷取自:
http://www.emersonprocess.com/raihome/documents/RAI_GC_Manual_GC_All_Modbus_Communications_Model_2500_3-9000-545-D_199211.pdf
這份文件



===================引 用 jow 文 章===================
以下省略
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#7 引用回覆 回覆 發表時間:2007-10-15 19:01:43 IP:123.193.xxx.xxx 訂閱
===================引 用 tyw6455 文 章===================
謝謝JOW兄給的程式
那是你的程式, 我只是將每次運算的結果, Add到 ListBox1中, 顯示出來而已 ^^

找了不少資料,有驗證了上面不管是查表或是用算的程式都OK的
只是很納悶用紙筆按照數學的邏輯方式下去算CRC的值
一直找不出來他的多項式到等是什麼

只知道在程式裡面用的多項式(0xA001:1010 0000 0000 0001)
Trace你的程式, 其中並沒有引用到你所說的多項式 0xA001 ^^


上篇所附的內容中, 最前面是手動推算...到 for loop i=1時, 與電腦
計算的結果相符:

0x0111 1111 1101 1111(0x7FDF)
>>1-------------------i==1,cChk==1
0x0011 1111 1110 1111(0x3FEF)


0x7FDF
i=1, cChk=1
0x3FEF
0x3FEF


再來是稍微修改了你的程式碼, 主要是 Keep一些運算過程的結果.

最後是電腦直接跑出來的結果, 以ListBox1->Items->SaveToFile(), 再
轉貼上來給你參考.

建議你Trace一下你自己的程式,

CRC 計算之初值 為 0xFFFF,
傳入的0x41,
其實在你自己推算的式子裡高低位元組錯置了,
並且也引用程式中沒用到的值 0xA001, 所以你推算的結果,
會與電腦不同..

僅供參考...^_^
編輯記錄
jow 重新編輯於 2007-10-15 19:03:58, 註解 無‧
jow 重新編輯於 2007-10-15 19:08:28, 註解 無‧
jow 重新編輯於 2007-10-15 19:11:55, 註解 無‧
jow 重新編輯於 2007-10-15 19:13:18, 註解 無‧
q023057866
一般會員


發表:0
回覆:1
積分:0
註冊:2010-01-08

發送簡訊給我
#8 引用回覆 回覆 發表時間:2012-06-07 17:33:27 IP:114.43.xxx.xxx 訂閱
想請教各位大大!!CRC16到底是怎麼算的,我在書上面看到說演算法
步驟1:令16位元的CRC暫存器之起始值為FFFFH
步驟2:將data第一個byte與CRC暫存器的低次位元組進行XOR,並將結果存回CRC暫存器中~~~
步驟7.......,這我有都看了,看有看沒有懂。
文中指的一個byte一個byte是00 10 60 01 01 23這樣嗎??
書中有提到命令0106001012348578,其中CRC16=8578,這是怎麼算出來的?
系統時間:2024-05-20 19:27:27
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!