免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4321 | 回复: 8
打印 上一主题 下一主题

[C++] C++ POCO 與 PHP 的 inflate deflate 無法互相壓縮與解壓縮 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-08-21 04:35 |只看该作者 |倒序浏览
本帖最后由 fiendcly 于 2012-08-21 07:12 编辑

Dears :

前言 -

各位大大安安 !!

SORRY 我來自台灣 用語如果 有不同的地方請多包含 ....

目前手上有個專案

有個功能是利用 SOCKET 將 資料 壓縮並且 送給其它 平台或環境做整合 及 P2P 等....



會採用 POCO 主要是 這個專案有用到 :

https://github.com/OpenRTMFP/Cumulus/wiki/_pages

剛好跟我目前要寫的東西很類似 , 所以我就用 POCO 當元件庫 寫這個專案看看...

可是一接到 PHP 上就有問題了.....

目前的測試結果是

PHP inflate , deflate => FLASH As3 inflate ,deflate ... << 正常 >>

C++ POCO inflate , deflate => PHP , FLAS AS3 inflate , deflaet <<錯誤>>


使用 C++ POCO libary

http://pocoproject.org/





#################################

測試 -

測試環境 :

作業系統 - Centos6.2 64
伺服器 - HP DL380 Gen8 , CPU XEON E52620

以下是我用 POCO 寫的 CODE :
Deflate :
  1. std::string Zlib::deflate (const std::string &source , int level = (-1))        {

  2.         std::istringstream in(source);
  3.         std::ostringstream out;
  4.         Poco::DeflatingOutputStream deflaterOut(out,DeflatingStreamBuf::STREAM_ZLIB,level);

  5.         // 這裡沒有使用 POCO 的 StreamCopier::copyStream 的原因是因為 , 沒法子 COPY  可能是 BUG.....
  6.         // POCO SUPPORT 是要收費 的 , 如果知道原因的也麻煩賜教 , 謝謝!!!!
  7.         // 寫到這裡時要小心....
  8.         // 在不得已的情況下 ,,,, 直接用這個方式 :
  9.         deflaterOut << in.str() ;

  10.         deflaterOut.close() ;  
  11.         deflateStr = out.str();
  12.         return deflateStr ;
  13. }
复制代码
Inflate :
  1. std::string Zlib::inflate (const std::string &source)   {
  2.         std::istringstream in(source);
  3.         std::ostringstream out;
  4.         Poco::InflatingInputStream inflaterIn(in);
  5.         StreamCopier::copyStream(inflaterIn , out);
  6.         inflateStr = out.str();
  7.         return inflateStr ;
  8. }
复制代码
PHP 就簡單多了 :
  1. gzDeflate($string,level = (defalut -1));
  2. gzInflate($string);
复制代码

測試結果分析 :
  1. SOURCE JSON STring :
  2. {"SID":"123456789","BID":"LD0001","DATA":{"args":{"name":"test1","passwd":"test1","item":["itme1","itme2","itme3","itme4"]}}}

  3. POCO Deflate :
  4. x▒▒V
  5. ▒#U▒R2426153▒▒T▒Qr▒▒▒.▒!▒JV▒J▒E▒▒ :/17(_▒Z\▒.H,..OA▒,I▒U▒▒ҹ▒~n▒▒6▒▒&J▒▒▒▒

  6. Lengh :
  7. 97

  8. Ascii Code :
  9. 120 156 171 86 10 246 116 81 178 82 50 52 50 54 49 53 51 183 176 84 210 81 114 2 139 248 184 24 24 24 24 2 185 46 142 33 142 74 86 213 74 137 69 233 197 32 58 47 49 55 21 40 95 146 90 92 2 146 46 72 44 46 46 79 65 18 200 44 73 205 85 178 138 6 210 185 169 16 126 110 170 17 148 54 134 210 38 74 177 181 181 181 0 13 213 35 85

  10. Hex Code :
  11. 78 9c ab 56 a f6 74 51 b2 52 32 34 32 36 31 35 33 b7 b0 54 d2 51 72 2 8b f8 b8 18 18 18 18 2 b9 2e 8e 21 8e 4a 56 d5 4a 89 45 e9 c5 20 3a 2f 31 37 15 28 5f 92 5a 5c 2 92 2e 48 2c 2e 2e 4f 41 12 c8 2c 49 cd 55 b2 8a 6 d2 b9 a9 10 7e 6e aa 11 94 36 86 d2 26 4a b1 b5 b5 b5 0 d d5 23 55

  12. PHP Deflate:
  13. ▒V
  14. ▒tQ▒R2426153▒▒T▒Qr▒▒▒.▒!▒JV▒J▒E▒▒ :/17(_▒Z\▒.H,..OA▒,I▒U▒▒ҹ▒~n▒▒6▒▒&J▒▒▒▒

  15. Lengh :
  16. 91


  17. Ascii Code :
  18. 171 86 10 246 116 81 178 82 50 52 50 54 49 53 51 183 176 84 210 81 114 2 139 248 184 24 24 24 24 2 185 46 142 33 142 74 86 213 74 137 69 233 197 32 58 47 49 55 21 40 95 146 90 92 2 146 46 72 44 46 46 79 65 18 200 44 73 205 85 178 138 6 210 185 169 16 126 110 170 17 148 54 134 210 38 74 177 181 181 181 0

  19. Hex Code :
  20. ab 56 a f6 74 51 b2 52 32 34 32 36 31 35 33 b7 b0 54 d2 51 72 2 8b f8 b8 18 18 18 18 2 b9 2e 8e 21 8e 4a 56 d5 4a 89 45 e9 c5 20 3a 2f 31 37 15 28 5f 92 5a 5c 2 92 2e 48 2c 2e 2e 4f 41 12 c8 2c 49 cd 55 b2 8a 6 d2 b9 a9 10 7e 6e aa 11 94 36 86 d2 26 4a b1 b5 b5 b5 0
复制代码
用 HEX 表來分析 :

POCO 在解壓縮和壓縮時 .

必需在

前面 : 多二個字元 ,  78 9c

後面 : 多了四個字元 ,   d d5 23 55


所以造成它跟 PHP 還有 FLASH 無法做 解壓縮和壓縮的動作.


有經驗的人可以分析一下狀況給在下聽嗎...

目前我暫時是硬改 前後的字元讓雙方可以溝通.



论坛徽章:
0
2 [报告]
发表于 2012-08-21 08:26 |只看该作者
本帖最后由 fiendcly 于 2012-08-21 08:31 编辑

我的媽啊~~

終於解決了...

再串一個資料加密的邏輯就可以去睡覺了....
  1. Client IP : 127.0.0.1
  2. Client Port : 36515
  3. Base64 Decode len :91
  4. Base64 DeCode     :

  5. Deflate len        : 97
  6. Deflate            :
  7. x▒▒V
  8. ▒#U▒R2426153▒▒T▒Qr▒▒▒.▒!▒JV▒J▒E▒▒ :/17(_▒Z\▒.H,..OA▒,I▒U▒▒ҹ▒~n▒▒6▒▒&J▒▒▒▒

  9. Base64 Encode      :
  10. eJyrVgr2dFGyUjI0MjYxNTO3sFTSUXICi/i4GBgYGAK5Lo4hjkpW1UqJRenFIDovMTcVKF+S
  11. WlwCki5ILC4uT0ESyCxJzVWyigbSuakQfm6qEZQ2htImSrG1tbUADdUjVQ==

  12. inflate            :
  13. {"SID":"123456789","BID":"LD0001","DATA":{"args":{"name":"test1","passwd":"test1","item":["itme1","itme2","itme3","itme4"]}}}


复制代码

论坛徽章:
0
3 [报告]
发表于 2012-08-21 13:46 |只看该作者
本帖最后由 fiendcly 于 2012-08-21 13:53 编辑

想哭.....

沒有人回 :

後來我查了一下...

原來 POCO 的 inflate 和 deflate 是使用 ZLIB.

我有試著 從 .h 檔的STRUCT 上分析 , 找到 GZLIP 格式插入 .... 但是不支援.



因為趕著要用 ...... 所以只好先自己硬改一個版本.....


>_<" 免費的就難搞..........


程式也改好了......
  1.         std::string fixsource;

  2.         zlibHeader[0] = 0x78  ;
  3.         zlibHeader[1] = 0x9c  ;
  4.         std::string zlibHeaderStr =  zlibHeader;
  5.         std::string fixZlibHeaderStr = zlibHeaderStr.substr(0,2); // 為什麼要再往前抽二個字元 , ( 因為 不知道為什麼我的 編譯器編出來的 CODE 往 fixsource 丟老是會多一個字元 , 為了穩定性加一下....... )

  6.         zlibEnd[0] = 0xd ;
  7.         zlibEnd[1] = 0xd5 ;
  8.         zlibEnd[2] = 0x23 ;
  9.         zlibEnd[3] = 0x55 ;
  10.         std::string zlibEndStr = zlibEnd ;
  11.         std::string fixZlibEndStr = zlibEndStr.substr(0,4);  

  12.         fixsource = fixZlibHeaderStr + source + fixZlibEndStr ; // 將 HEADER 和 END 的 部份修改成 GZIP 看的懂的格式....
  13.       
  14.         std::istringstream in(source);

复制代码
執行 UNIT TEST .....................
  1. Convert To HEX   :
  2. ffffffab 56 a fffffff6 74 51 ffffffb2 52 32 34 32 36 31 35 33 ffffffb7 ffffffb0 54 ffffffd2 51 72 2 ffffff8b fffffff8 ffffffb8 18 18 18 18 2 ffffffb9 2e ffffff8e 21 ffffff8e 4a 56 ffffffd5 4a ffffff89 45 ffffffe9 ffffffc5 20 3a 2f 31 37 15 28 5f ffffff92 5a 5c 2 ffffff92 2e 48 2c 2e 2e 4f 41 12 ffffffc8 2c 49 ffffffcd 55 ffffffb2 ffffff8a 6 ffffffd2 ffffffb9 ffffffa9 10 7e 6e ffffffaa 11 ffffff94 36 ffffff86 ffffffd2 26 4a ffffffb1 ffffffb5 ffffffb5 ffffffb5 0 0 0 0 0 Inflate  Success
  3. {"SID":"123456789","BID":"LD0001","DATA":{"args":{"name":"test1","passwd":"test1","item":["itme1","itme2","itme3","itme4"]}}}
复制代码
XD 寫支 DOS 的攻擊程式狂丟...... 還沒死掉 應該修好了 >_<"

我覺得我下次還是愛用 LINUX 內建的 函式庫比較安全.... 肝都快壞了~~~


论坛徽章:
0
4 [报告]
发表于 2012-08-22 08:01 |只看该作者
本帖最后由 fiendcly 于 2012-08-22 08:03 编辑

一樣如上 , 因為 POCO 的 zlib 無法解壓縮 gzip 格式.

所以我我另外又寫了支 gzip inflate .....


這樣你的 POCO 就同時可以用 GZIP 和 ZLIB 做 INFLATE 和 DEFLATE 了 :


  1. /*
  2. * gzip deflate 字串壓縮
  3. */

  4. std::string Zlib::gzdeflate (const std::string &source , int level = (-1))      {

  5.         std::istringstream in(source);
  6.         std::ostringstream out;
  7.         Poco::DeflatingOutputStream deflaterOut(out,DeflatingStreamBuf::STREAM_ZLIB,level); /// 這裡不用管它 ,我用 DeflatingStreamBuf::STREAM_GZIP 是不 WORK 的 , 它是免費的不是故意的就是還沒寫好.
  8.         deflaterOut << in.str() ;
  9.         deflaterOut.close() ;
  10.         std::string zlibDeflateStr ;
  11.         zlibDeflateStr = out.str();
  12.         zlibDeflateStr = zlibDeflateStr.substr(2,zlibDeflateStr.length()-6); // 將 ZIP 的 HEADER 及 END 拿掉 , 前二個字元 , 後六個字元.
  13.         deflateStr = zlibDeflateStr ;
  14.         return deflateStr ;
  15. }


复制代码

论坛徽章:
0
5 [报告]
发表于 2012-08-22 08:39 |只看该作者

我把 整理好的 程式 分享在 :

http://bbs.chinaunix.net/thread-3766597-1-1.html

請多給小弟一點意見.

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
6 [报告]
发表于 2012-08-22 10:13 |只看该作者
发帖支持下台湾的朋友,恭喜问题解决。
我不懂PHP

论坛徽章:
0
7 [报告]
发表于 2012-08-22 18:15 |只看该作者
本帖最后由 fiendcly 于 2012-08-22 18:26 编辑
hellioncu 发表于 2012-08-22 10:13
发帖支持下台湾的朋友,恭喜问题解决。
我不懂PHP


我開始考慮要把 POCO 從我的專案裡慢慢抽掉了!!!!!( 這是氣話.....等產品出來了再慢慢抽 >_<" )

還好我另外有一半的東西是用 BOOST 組裝的.....

雖然~BOOST 編譯起來很慢... 但是至少沒那麼多問題 >_<" ( 可能是比較熟的關係...... )

inflate deflate 事件結束後.

又發生 Base 64 給我插入 \r 的問題.

害我又在那比對半天 HEX CODE .

動畫 TEAM 和 WEB TEAM 一直跟我報怨 BASE 64 我經過加密演算後 ( 我直接寫支 公式打亂 BASE64 的內容 )

結果他們解密後結果每次都跟我不一樣!! 因為我老是 在 第 72 個字元後自動插入


                        if (_buf.sputc('\r') == eof) return eof;
                        if (_buf.sputc('\n') == eof) return eof;


所以我的 HEX 比較表如下 :

71 31 59 4b 39 6e 52 52 73 6c 49 79 4e 44 49 32 4d 54 55 7a 74 37 42 55 30 6c 46 79 41 6f 76 34 75 42 67 59 47 42 67 43 75 53 36 4f 49 59 35 4b 56 74 56 4b 69 55 58 70 78 53 41 36 4c 7a 45 33 46 53 68 66 6b 6c 70 63 d a 41 70 49 75 53 43 77 75 4c 6b 39 42 45 73 67 73 53 63 31 56 73 6f 6f 47 30 72 6d 70 45 48 35 75 71 68 47 55 4e 6f 62 53 4a 6b 71 78 74 62 57 31 41 41 3d 3d

d = 13 = \r
a = 10 = \n

真的很想罵粗話..... 害我又浪費一個早上.....


  1. Base64EncoderBuf::Base64EncoderBuf(std::ostream& ostr):
  2.         _groupLength(0),
  3.         _pos(0),
  4.         _lineLength(72),
  5.         _buf(*ostr.rdbuf())
  6. {
  7. }


  8. int Base64EncoderBuf::writeToDevice(char c)
  9. {
  10.         static const int eof = std::char_traits<char>::eof();

  11.         _group[_groupLength++] = (unsigned char) c;
  12.         if (_groupLength == 3)
  13.         {
  14.                 unsigned char idx;
  15.                 idx = _group[0] >> 2;
  16.                 if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
  17.                 idx = ((_group[0] & 0x03) << 4) | (_group[1] >> 4);
  18.                 if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
  19.                 idx = ((_group[1] & 0x0F) << 2) | (_group[2] >> 6);
  20.                 if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
  21.                 idx = _group[2] & 0x3F;
  22.                 if (_buf.sputc(OUT_ENCODING[idx]) == eof) return eof;
  23.                 _pos += 4;
  24.                 if (_lineLength > 0 && _pos >= _lineLength)
  25.                 {
  26.                        // 就是這裡~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~~太雞婆了~

  27.                         if (_buf.sputc('\r') == eof) return eof;
  28.                         if (_buf.sputc('\n') == eof) return eof;
  29.                         _pos = 0;
  30.                 }
  31.                 _groupLength = 0;
  32.         }
  33.         return charToInt(c);
  34. }
复制代码

论坛徽章:
0
8 [报告]
发表于 2012-08-22 18:40 |只看该作者
我後來研究了一下 POCO BASE64 到底都用在那裡 :

  1. [root@FIEND poco-1.4.3p1-all]# find . -type f -exec grep -l "Base64" {} \; -print | uniq | grep -v .svn | grep -v vc | grep -v vs
  2. ./Net/testsuite/src/MailMessageTest.h
  3. ./Net/testsuite/src/MailMessageTest.cpp
  4. ./Net/src/HTTPClientSession.cpp
  5. ./Net/src/WebSocket.cpp
  6. ./Net/src/SMTPClientSession.cpp
  7. ./Net/src/HTTPBasicCredentials.cpp
  8. ./Net/src/MailMessage.cpp
  9. ./Foundation/Makefile
  10. ./Foundation/foundation.vmsbuild
  11. ./Foundation/testsuite/TestSuite.vxbuild
  12. ./Foundation/testsuite/testsuite.vmsbuild
  13. ./Foundation/testsuite/src/Base64Test.cpp
  14. ./Foundation/testsuite/src/Base64Test.h
  15. ./Foundation/testsuite/src/StreamsTestSuite.cpp
  16. ./Foundation/testsuite/Makefile-Driver
  17. ./Foundation/include/Poco/Base64Encoder.h
  18. ./Foundation/include/Poco/Base64Decoder.h
  19. ./Foundation/samples/base64encode/src/base64encode.cpp
  20. ./Foundation/samples/base64decode/src/base64decode.cpp
  21. ./Foundation/src/Base64Decoder.cpp
  22. ./Foundation/src/Base64Encoder.cpp
  23. ./Foundation/Foundation.vxbuild
  24. ./doc/99100-ReleaseNotes.page
  25. ./doc/99300-AndroidPlatformNotes.page
  26. ./Crypto/include/Poco/Crypto/Cipher.h
  27. ./Crypto/src/Cipher.cpp
  28. ./CHANGELOG
  29. ./MANIFEST
复制代码
./Net/src/HTTPClientSession.cpp
./Net/src/WebSocket.cpp
./Net/src/SMTPClientSession.cpp
./Net/src/HTTPBasicCredentials.cpp
./Net/src/MailMessage.cpp

Base64 如果用在 MAIL 上的話.....

這個格式完全合法.

走 HTTP 也 OK ..........


论坛徽章:
0
9 [报告]
发表于 2012-08-22 20:11 |只看该作者
本帖最后由 fiendcly 于 2012-08-22 20:14 编辑

看來找時間要把 POCO Base64 抽掉了 :

拿來做 SERVER 端 雖然 元件的單元測試 數值是 小數點五位以下 ... 不過也不能比 SCRIPT 寫的程式...慢吧~~~~~

[root@FIEND wge_server]# ./test/base64
unittest encode success!!
Connection : 100001 , use time : 0.807738
AVG : 123803 (Request/s)
AVG Toime : 8.077299E-06 (s/Request)

unittest decode success!!
Connection : 100001 , use time : 1.190952
AVG : 83967 (Request/s)
AVG Toime : 1.190940E-05 (s/Request)



#############################################################

在 PHP 5 底下 用 PHP 預設的 函式測試..... ( 我有 優化過 PHP 底層所以比 原本的 PHP 快四成效率. )

test base64Encode :
Runing : 100000
result :
RklFTkQgdGVzdCBiYXNlIFN0cmluZyBGSUVORCB0ZXN0IGJhc2UgU3RyaW5nIEZJRU5EIHRlc3QgYmFzZSBTdHJpbmcgRklFTkQgdGVzdCBiYXNlIFN0cmluZyBGSUVORCB0ZXN0IGJhc2UgU3RyaW5nIEZJRU5EIHRlc3QgYmFzZSBTdHJpbmcgRklFTkQgdGVzdCBiYXNlIFN0cmluZyBGSUVORCB0ZXN0IGJhc2UgU3RyaW5nIEZJRU5EIHRlc3QgYmFzZSBTdHJpbmcgRklFTkQgdGVzdCBiYXNlIFN0cmluZyBGSUVORCB0ZXN0IGJhc2UgU3RyaW5nIA==NO : 100000 base64_encode() Success!!
The base64_encode() use Time : 0.4520001411438
AVG Time : 4.520001E-6  s/request



test base64Decode :
Runing : 100000
result :
FIEND test base String FIEND test base String FIEND test base String FIEND test base String FIEND test base String FIEND test base String FIEND test base String FIEND test base String FIEND test base String FIEND test base String FIEND test base String NO : 100000 base64_decode() Success!!
The base64_decode() use Time : 0.48141694068909
AVG Time : 4.814169E-6  s/request
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP