使用wireshark抓包,本地環回測試通信數據已經通過SM4國密算法加密

具體操作

  • 本實驗采用 本地環回測試
  • 開啟wireshark抓包工具,設定端口號 tcp.port == 5099 (5099為服務端對外開啟服務的端口號),不可以使用ip.addr指定ip地址,因為本地環回測試,相關信息太多,使用端口抓包最為簡單
  • 首先開啟服務端,然后開啟客戶端,服務端開啟之后輸出 "Bind returned success",并輸出客戶端連接通信使用的端口號,然后客戶端會使用socket通信傳輸經過SM4對稱加密算法加密返回的密文
  • 密文存儲格式是字符串,表示形式是十六進制;socket通信的時候會將這個字符串再次編碼為十六進制,因此使用wireshark抓包數據之后 需要對攔截的數據進行解碼 (十六進制 轉 字符串)
  • hex轉str - 在線工具
  • 客戶端發送數據完畢之后,輸出Client:sending data test,請按任意鍵退出
  • 服務端打印輸出 客戶端發送數據的數據 以及對應的長度等信息,輸出 Connect closed,結束通信

服務端

?客戶端

?wireshark抓包

  • 客戶端 端口號 向 服務端 端口號 發送33字節數據

  • ?點擊 Data,查看下窗口,左邊是數據的十六進制,右邊是字符串

  • ?將wireshark抓到的數據和server接收到的數據對比,數據一致
  • 表明客戶端和發送端數據傳輸是經過SM4算法加密的

參考鏈接

  • https://blog.csdn.net/CHYabc123456hh/article/details/122049078
  • SM4 ECB加密模式 數據對比試驗論證_CHYabc123456hh的博客-CSDN博客
  • 數據填充規則之PKCS7_CHYabc123456hh的博客-CSDN博客
  • C++ Byte轉十六進制字符串輸出_CHYabc123456hh的博客-CSDN博客
  • 使用國密瀏覽器和使用Wireshark進行國密抓包_CHYabc123456hh的博客-CSDN博客_gmssl wireshark
  • Socket代碼實現服務端 和 客戶端之間通信_CHYabc123456hh的博客-CSDN博客_c++實現客戶端socket
  • Socket編程 涵蓋代碼和函數參數介紹_CHYabc123456hh的博客-CSDN博客
  • 本地搭建server和客戶端使用端口進行數據通信,使用Wireshark抓取127.0.0.1環回地址并分析通信數據_CHYabc123456hh的博客-CSDN博客
  • 驗證客戶端和服務端可以傳輸經SM4加密的密文數據,從而驗證發送數據已使用服務器密碼機進行SM4加密,而不是隨便的字符串亂碼_CHYabc123456hh的博客-CSDN博客

服務端代碼

// sdf_cpp_warpper.cpp : 此文件包含 "main" 函數。程序執行將在此處開始并結束。
// server端#ifndef UNICODE
#define UNICODE
#endif#define WIN32_LEAN_AND_MEAN#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <iomanip>
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>#include "sdf_warpper.hpp"
#include "cstring"#pragma comment(lib, "Ws2_32.lib")
#pragma comment(lib,"libhsm_core.lib")#define DEFAULT_BUFLEN 1024
using namespace std;typedef std::vector<unsigned char> bytes;
std::string BytesToStr(const bytes& in)
{bytes::const_iterator from = in.cbegin();bytes::const_iterator to = in.cend();std::ostringstream oss;for (; from != to; ++from)oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(*from);return oss.str();
}void sm4_encrypt_decrypt_demo() {sdf_qax::SDF_warpper sdf_warpper("{\"device_type\": \"rpc\",\"device_socket\": \"172.22.14.231:5000\"}");//char a[16] = { '1','0','0','0','0','2','4','5','6','7','2','1','3','4','5','6' };char a[]{ '0','0','0','0','0','0','0','0','0','0','0','0','0','0' };//char a[]{ 00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };//std::cout << "input_data: ";std::cout << "char類型數據: ";
/*	for (auto i : a) {std::cout << i << " ";}  *///std::cout << std::endl;			  bytes input(a, a + 15);for (auto i : input) {std::cout << i;}			 std::cout << std::endl;std::cout << "char類型數據 轉十六進制 輸出: ";std::cout << BytesToStr(input) << std::endl;		   char outbuffer[32]{ 0 };int out_buffer_true_length = 0;sdf_warpper.sm4_symmetry_encrypt((uint8_t *)sdf_warpper.getStaticKey(), a, sizeof(a) / sizeof(char), outbuffer, &out_buffer_true_length);std::cout << "cipher data with padding length: " << out_buffer_true_length << std::endl;char static_key[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };bytes input_3(static_key, static_key + 15);std::cout << "static_key數據 轉十六進制 輸出: ";std::cout << BytesToStr(input_3) << std::endl;/*	for (char i : outbuffer) {std::cout << i;}							   */bytes input_2(outbuffer, outbuffer + out_buffer_true_length);std::cout << "密文數據輸出:";std::cout << BytesToStr(input_2) << std::endl;//std::cout << std::endl;std::cout << "true array length: " << strlen(outbuffer) << std::endl;char decrypt_result[32]{ 0 };int out_true_length = 0;sdf_warpper.sm4_symmetry_decrypt((uint8_t *)sdf_warpper.getStaticKey(), outbuffer, out_buffer_true_length, decrypt_result, &out_true_length);std::cout << "decrypt result data: ";for (int i = 0; i < strlen(decrypt_result); i++) {std::cout << decrypt_result[i];}std::cout << std::endl;
}ECCCipher cipher;   //密文存儲結構體void sm2_encrypt_decrypt_demo() {sdf_qax::SDF_warpper sdf_warpper2("{\"device_type\": \"rpc\",\"device_socket\": \"172.22.14.231:5000\"}");char a[]{ '3','4','5' };std::cout << "input_data: ";for (char i : a) {std::cout << i;}std::cout << std::endl;sdf_warpper2.sm2_internal_encrypt(1, a, 3, &cipher);char decrypt_result[256]{ 0 };int out_true_length = 0;sdf_warpper2.sm2_internal_decrypt(1, &cipher, reinterpret_cast<sdf_uint8_t *>(decrypt_result), &out_true_length, nullptr, 0);std::cout << "Data length after decryption: " << out_true_length << std::endl;std::cout << "Data after decryption: ";for (int i = 0; i < out_true_length; i++) {std::cout << decrypt_result[i];}std::cout << std::endl;
}void main()
{//Initialze winsockWSADATA wsaData;if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){std::cout << "Can't Initialize winsock!Quiting!" << std::endl;;return;}//Creste a sockrtSOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);if (sockSrv == INVALID_SOCKET) {wprintf(L"Can't create a socket with error %d\n", WSAGetLastError());WSACleanup();return;}//Bind the socket to an ip address and portint port = 5099;SOCKADDR_IN addrSrv;addrSrv.sin_family = AF_INET;addrSrv.sin_port = htons(port); //1024以上的端口號addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//Bind the socketint retVal = bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));if (retVal == SOCKET_ERROR) {printf("Failed bind:%d\n", WSAGetLastError());closesocket(sockSrv);WSACleanup();return;}else {std::cout << "Bind returned success" << std::endl;}//Tell winsock the socket is for listeningif (listen(sockSrv, SOMAXCONN) == SOCKET_ERROR) {printf("Listen failed:%d", WSAGetLastError());return;}//wait for a connectionSOCKADDR_IN addrClient;int clientSize = sizeof(addrClient);SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &clientSize);if (sockConn == SOCKET_ERROR) {wprintf(L"accept failed with error: %ld\n", WSAGetLastError());closesocket(sockSrv);WSACleanup();return;}char host[NI_MAXHOST];       //Client's remote namechar service[NI_MAXSERV];    //Service (i.e. port)the client is connect onZeroMemory(host, NI_MAXHOST);//Same as memset(host,0,NI_MAXHOST)ZeroMemory(service, NI_MAXSERV);if (getnameinfo((sockaddr*)&addrClient, sizeof(addrClient), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0) {std::cout << "connect on port " << service << std::endl;}else {inet_ntop(AF_INET, &addrClient.sin_addr, host, NI_MAXHOST);std::cout << host << " connect on port " << ntohs(addrClient.sin_port) << std::endl;}//while loop:accept and echo message back to clientchar recvbuf[DEFAULT_BUFLEN] = "";int recvbuflen = DEFAULT_BUFLEN;memset(recvbuf, 0, sizeof(recvbuf));char sendbuf[] = "Client: sending data test\n";retVal = send(sockConn, sendbuf, sizeof(sendbuf), 0);if (retVal == SOCKET_ERROR) {wprintf(L"send failed with error: %d\n", WSAGetLastError());closesocket(sockSrv);WSACleanup();return;}do {retVal = recv(sockConn, recvbuf, recvbuflen, 0);if (retVal > 0) {wprintf(L"Bytes received: %d\n", retVal);printf("%s\n", recvbuf);}else if (retVal == 0)wprintf(L"Connection closed\n");elsewprintf(L"recv failed with error: %d\n", WSAGetLastError());} while (retVal > 0);closesocket(sockConn);//close socketclosesocket(sockSrv);//close winsockWSACleanup();system("pause");
}// 運行程序: Ctrl + F5 或調試 >“開始執行(不調試)”菜單
// 調試程序: F5 或調試 >“開始調試”菜單// 入門使用技巧: 
//   1. 使用解決方案資源管理器窗口添加/管理文件
//   2. 使用團隊資源管理器窗口連接到源代碼管理
//   3. 使用輸出窗口查看生成輸出和其他消息
//   4. 使用錯誤列表窗口查看錯誤
//   5. 轉到“項目”>“添加新項”以創建新的代碼文件,或轉到“項目”>“添加現有項”以將現有代碼文件添加到項目
//   6. 將來,若要再次打開此項目,請轉到“文件”>“打開”>“項目”并選擇 .sln 文件

客戶端代碼

// sdf_cpp_warpper.cpp : 此文件包含 "main" 函數。程序執行將在此處開始并結束。
// client端#ifndef UNICODE
#define UNICODE
#endif#define WIN32_LEAN_AND_MEAN#include <iostream>
#include <stdio.h>
#include <string>
#include <sstream>
#include <vector>
#include <iomanip>
#include <winsock2.h>
#include <Ws2tcpip.h>#include "sdf_warpper.hpp"
#include "cstring"#pragma comment(lib,"libhsm_core.lib")
#pragma comment(lib, "Ws2_32.lib")
using namespace std;typedef std::vector<unsigned char> bytes;
std::string BytesToStr(const bytes& in)
{bytes::const_iterator from = in.cbegin();bytes::const_iterator to = in.cend();std::ostringstream oss;for (; from != to; ++from)oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(*from);return oss.str();
}void sm4_encrypt_decrypt_demo(char* outbuffer,int & out_buffer_true_length) {sdf_qax::SDF_warpper sdf_warpper("{\"device_type\": \"rpc\",\"device_socket\": \"172.22.14.231:5000\"}");//char a[16] = { '1','0','0','0','0','2','4','5','6','7','2','1','3','4','5','6' };char a[]{ '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0' };//char a[]{ 00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };//std::cout << "input_data: ";//std::cout << "char類型數據: ";/*	for (auto i : a) {std::cout << i << " ";}  *///std::cout << std::endl;			  bytes input(a, a + 15);
/*	for (auto i : input) {std::cout << i;}std::cout << std::endl;std::cout << "char類型數據 轉十六進制 輸出: ";std::cout << BytesToStr(input) << std::endl;		   *///char outbuffer[32]{ 0 };//int out_buffer_true_length = 0;sdf_warpper.sm4_symmetry_encrypt((uint8_t*)sdf_warpper.getStaticKey(), a, sizeof(a) / sizeof(char), outbuffer, &out_buffer_true_length);
//	std::cout << "cipher data with padding length: " << out_buffer_true_length << std::endl;char static_key[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };bytes input_3(static_key, static_key + 15);
/*	std::cout << "static_key數據 轉十六進制 輸出: ";std::cout << BytesToStr(input_3) << std::endl;			 *//*	for (char i : outbuffer) {std::cout << i;}							   */bytes input_2(outbuffer, outbuffer + out_buffer_true_length);//std::cout << "密文數據輸出:";//std::cout << BytesToStr(input_2) << std::endl;//std::cout << std::endl;
//	std::cout << "true array length: " << strlen(outbuffer) << std::endl;char decrypt_result[32]{ 0 };int out_true_length = 0;sdf_warpper.sm4_symmetry_decrypt((uint8_t*)sdf_warpper.getStaticKey(), outbuffer, out_buffer_true_length, decrypt_result, &out_true_length);//std::cout << "decrypt result data: ";
/*	for (int i = 0; i < strlen(decrypt_result); i++) {std::cout << decrypt_result[i];				    }							   */std::cout << std::endl;
}
ECCCipher cipher;   //密文存儲結構體void sm2_encrypt_decrypt_demo() {sdf_qax::SDF_warpper sdf_warpper2("{\"device_type\": \"rpc\",\"device_socket\": \"172.22.14.231:5000\"}");	char a[]{ '3','4','5' };std::cout << "input_data: ";for (char i : a) {std::cout << i;}std::cout << std::endl;sdf_warpper2.sm2_internal_encrypt(1, a, 3, &cipher);char decrypt_result[256]{ 0 };int out_true_length = 0;sdf_warpper2.sm2_internal_decrypt(1, &cipher, reinterpret_cast<sdf_uint8_t *>(decrypt_result), &out_true_length, nullptr, 0);std::cout << "Data length after decryption: " << out_true_length << std::endl;std::cout << "Data after decryption: ";for (int i = 0; i < out_true_length; i++) {std::cout << decrypt_result[i];}std::cout << std::endl;
}void main() {//Initialze winsockWSADATA wsaData;if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){std::cout << "Can't Initialize winsock!Quiting!" << std::endl;;return;}//Creste a sockrtSOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);if (sockClient == INVALID_SOCKET) {wprintf(L"Can't create a socket with error %d\n", WSAGetLastError());WSACleanup();return;}//Bind the socket to an ip address and portint port = 5099;SOCKADDR_IN addrSrv;addrSrv.sin_family = AF_INET;addrSrv.sin_port = htons(5099);//addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");inet_pton(AF_INET, "127.0.0.1", &addrSrv.sin_addr.S_un.S_addr);char buff[1024];memset(buff, 0, sizeof(buff));//向服務器發出連接請求if (connect(sockClient, (struct  sockaddr*) & addrSrv, sizeof(addrSrv)) == INVALID_SOCKET) {printf("Connect failed:%d", WSAGetLastError());return;}else{//接收數據recv(sockClient, buff, sizeof(buff), 0);printf("%s\n", buff);}//發送數據//const char* buffSend = "hello, this is a Client....";//send(sockClient, buffSend, strlen(buffSend) + 1, 0);//	char sendbuf[BUFSIZ];
//	ZeroMemory(sendbuf, BUFSIZ);
/*	strcpy_s(sendbuf, str.c_str());if (send(sockClient, sendbuf, strlen(sendbuf) + 1, 0) == SOCKET_ERROR) {wprintf(L"send failed with error: %d\n", WSAGetLastError());closesocket(sockClient);WSACleanup();break;}*/char outbuffer[32]{ 0 };int out_buffer_true_length = 0;sm4_encrypt_decrypt_demo(outbuffer,out_buffer_true_length);bytes input_2(outbuffer, outbuffer + out_buffer_true_length);//std::cout << "密文數據輸出:";//std::cout << BytesToStr(input_2) << std::endl;//printf("%d", strlen(buffSend) + 1);std::string return_value(BytesToStr(input_2));//std::cout << return_value << std::endl;char sendbuf[BUFSIZ];ZeroMemory(sendbuf, BUFSIZ);strcpy_s(sendbuf, return_value.c_str());if (send(sockClient, sendbuf, strlen(sendbuf) + 1, 0) == SOCKET_ERROR) {wprintf(L"send failed with error: %d\n", WSAGetLastError());closesocket(sockClient);WSACleanup();exit(-1);}//關閉套接字closesocket(sockClient);WSACleanup();system("pause");}// 運行程序: Ctrl + F5 或調試 >“開始執行(不調試)”菜單
// 調試程序: F5 或調試 >“開始調試”菜單// 入門使用技巧: 
//   1. 使用解決方案資源管理器窗口添加/管理文件
//   2. 使用團隊資源管理器窗口連接到源代碼管理
//   3. 使用輸出窗口查看生成輸出和其他消息
//   4. 使用錯誤列表窗口查看錯誤
//   5. 轉到“項目”>“添加新項”以創建新的代碼文件,或轉到“項目”>“添加現有項”以將現有代碼文件添加到項目
//   6. 將來,若要再次打開此項目,請轉到“文件”>“打開”>“項目”并選擇 .sln 文件

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/446137.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446137.shtml
英文地址,請注明出處:http://en.pswp.cn/news/446137.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

public 函數_UE4精品教程 | 渲染編程(C++篇)【第三卷:從仿函數到std::function再到虛幻4Delegate】...

本文轉載于YivanLee知乎作者專題目錄鏈接&#xff1a;https://zhuanlan.zhihu.com/p/67694999這幾天研究了一下虛幻4的delegate&#xff0c;但是想要理解這個&#xff0c;還得從仿函數說起。下面是一段代碼例子&#xff1a;class MyFunctor{ public: int operator()(int …

C語言深度剖析書籍學習記錄 第一章 關鍵字

C語言標準定義了32個關鍵字 union聲明聯合數據類型 Union declaration - cppreference.com維護足夠的空間來置放多個數據成員中的“一種”&#xff0c;而不是為每一個數據成員配置空間&#xff0c;在 union 中所有的數據成員共用一個空間&#xff0c;同一時間只能儲存其中一個…

js頁面自適應屏幕大小_移動端自適應布局方法的calc()與vw

前端人員在處理移動端自適應布局時&#xff0c;目前前端最流行的方法應該就是使用媒體查詢&#xff0c;來設置HTML的字體大小&#xff0c;然后用rem為單位對Dom的寬高進行設置&#xff0c;這個方法的優勢在于兼容性方面很好&#xff0c;劣勢則在于當前市場上不同的機型太多&…

C語言深度剖析書籍學習記錄 第二章 符號

\ 連接符號&#xff0c;// \ 可以把下一行也注釋調編譯器 刪除注釋時&#xff0c;會使用空格進行替代

詳細描述三個適于瀑布模型的項目_IT項目管理筆記——方法選擇和軟件評估

一、管理需求為什么要管理需求&#xff1f;避免失敗&#xff0c;提高項目的成功率和需求管理所帶來的其他好處軟件生命周期中&#xff0c;一個錯誤發現得越晚&#xff0c;修復錯誤的費用越高許多錯誤是潛伏的&#xff0c;并且在錯誤產生后很長一段時間才被檢查出來在需求階段&a…

Socket通信 客戶端加密數據,傳遞數據密文到服務端,服務端解密密文 輸出明文

server // sdf_cpp_warpper.cpp : 此文件包含 "main" 函數。程序執行將在此處開始并結束。 // server端#ifndef UNICODE #define UNICODE #endif#define WIN32_LEAN_AND_MEAN#include <iostream> #include <string> #include <sstream> #include …

主進程中發生了一個javascript錯誤_知道html5 Web Worker標準嗎?能實現JavaScript的多線程?

js為什么是單線程&#xff1f;主要是因為最開始javascript是單純的服務于瀏覽器的一種腳步語言(那時候沒有nodejs)。瀏覽器是為了渲染網頁&#xff0c;通過dom與用戶交互&#xff0c;如果一個線程需要給dom執行click事件&#xff0c;而另一個進程要刪除這個dom&#xff0c;這2個…

C語言深度剖析書籍學習記錄 第三章 預處理

宏 _LINE_ 表示正在編譯的文件的行號_FILE_ 表示正在編譯的文件的名字_DATE_ 表示編譯時刻的日期字符串&#xff0c;例如: "25 Dec 2007"_TIME_ 表示編譯時刻的時間字符串&#xff0c;例如: "12:30:55"_STDC_ 判斷該文件是不是定義成標準 C 程序宏名的書寫…

js正則限制字符串長度_正則筆記(3)萬字長文,慎點。

正則講了很久&#xff0c;也拖了很久&#xff0c;今天看看怎么用吧&#xff0c;后續更文應該會比較準勤快了。:-)書接上文【正則筆記(2)】。這次我們來看看正則的使用&#xff1a;(注&#xff1a;斜體表示為對應規則寫出的正則表達式)一、 常用的正則表達式&#xff1a;1. 驗證…

C語言深度剖析書籍學習記錄 第四章 指針和數組

p 稱為指針變量,p 里存儲的內存地址處的內存稱為 p 所指向的內存。 指針變量 p 里存儲的任何數據都將被當作地址來處理一個基本的數據類型(包括結構體等自定義類型)加上“*” 號就構成了一個指針類型的模子。這個模子的大小是一定的&#xff0c;與“*”號前面的數據類型無 關。…

js中select下拉框重置_如何利用CSS3制作炫酷的下拉框

很多小伙伴都不清楚CSS3是做什么&#xff1f;用途是什么&#xff1f;接下來我就給展示一個css3制作一個炫酷下拉框。其實不只是這些&#xff0c;還有很多。CSS3是CSS(層疊樣式表)技術的升級版本&#xff0c;于1999年開始制訂&#xff0c;2001年5月23日W3C完成了CSS3的工作草案&…

select選擇框必輸校驗_輪子這么多,我們為什么選擇自研NewSQL

作者介紹李鑫&#xff0c;滴滴資深軟件開發工程師&#xff0c;多年分布式存儲領域設計及開發經驗。曾參與NoSQL/NewSQL數據庫Fusion、分布式時序數據庫sentry、NewSQL數據庫SDB等系統的設計開發工作。一、背景Fusion-NewSQL是由滴滴自研的在分布式KV存儲基礎上構建的NewSQL存儲…

C語言深度剖析書籍學習記錄 第五章 內存管理

常見的內存錯誤 定義了指針變量&#xff0c;但是沒有為指針分配內存&#xff0c;即指針沒有指向一塊合法的內存。 結構體成員指針未初始化 很多初學者犯了這個錯誤還不知道是怎么回事。這里定義了結構體變量 stu&#xff0c;但是他沒 想到這個結構體內部 char *name 這成員在定…

怎么改電腦網絡ip地址_拋棄重啟路由器獲取ip地址方式,巧妙運用ip代理改IP工具...

網絡是簡單的也是復雜的&#xff0c;在如此龐大的網絡世界里有太多的不確定因素&#xff0c;導致我們遇到IP限制問題&#xff0c;從而影響到我們的網絡訪問&#xff0c;而大家都知道&#xff0c;如果遇到ip被限制的問題&#xff0c;最快速直接的辦法就是把被限制的ip更換一個新…

C語言深度剖析書籍學習記錄 第六章 函數

函數的好處 1、降低復雜性:使用函數的最首要原因是為了降低程序的復雜性&#xff0c;可以使用函數來隱含信息&#xff0c;從而使你不必再考慮這些信息。2、避免重復代碼段:如果在兩個不同函數中的代碼很相似&#xff0c;這往往意味著分解工作有誤。這時&#xff0c;應該把兩個…

如何把word分裝到兩個byte_如何核對兩個Word文檔的內容差別?同事加班半小時,我只花了30秒...

昨天下班前&#xff0c;老板突然發了兩份Word文檔過來&#xff0c;一份是原稿&#xff0c;還有一份是修訂稿&#xff0c;叫我們找出兩份文檔的內容差別之處&#xff0c;我只花了30秒就搞定了&#xff0c;然后準時下班&#xff01;你想知道我是怎么操作的嗎&#xff1f;下面小源…

stm32f767中文手冊_ALIENTEK 阿波羅 STM32F767 開發板資料連載第五章 SYSTEM 文件夾

1)實驗平臺&#xff1a;alientek 阿波羅 STM32F767 開發板2)摘自《STM32F7 開發指南(HAL 庫版)》關注官方微信號公眾號&#xff0c;獲取更多資料&#xff1a;正點原子第五章 SYSTEM 文件夾介紹第三章&#xff0c;我們介紹了如何在 MDK5 下建立 STM32F7 工程。在這個新建的工程之…

手機安卓學習 內核開發

官網開源代碼 Documentation - MiCode/Xiaomi_Kernel_OpenSource - Sourcegraph Xiaomi 11T Pro GitHub - MiCode/Xiaomi_Kernel_OpenSource: Xiaomi Mobile Phone Kernel OpenSourceAndroid 開源項目 | Android Open Source Project google安卓官網 目錄概覽 參考…

vs 啟動調用的目標發生異常_如何解決不可測、異常場景的問題?

阿里QA導讀&#xff1a;在軟件研發過程中&#xff0c;發布前跨多個系統的聯調測試是不可或缺的一環&#xff0c;而在聯調過程中&#xff0c;經常會遇到一些比較棘手的困難&#xff0c;阻塞整個聯調進程。其中比較典型的有&#xff1a;第三方的研發節奏不一致&#xff0c;導致無…