openssl里面有很多用于摘要哈希、加密解密的算法,方便集成于工程项目,被广泛应用于网络报文中的安全传输和认证。下面以md5,sha256,des,rsa几个典型的api简单使用作为例子。

算法介绍

md5:https://en.wikipedia.org/wiki/MD5

sha256:https://en.wikipedia.org/wiki/SHA-2

des: https://en.wikipedia.org/wiki/Data_Encryption_Standard

rsa: https://en.wikipedia.org/wiki/RSA_(cryptosystem)

工程配置

以windows下为例

  1. 编译openssl库,得到头文件include和链接库lib和dll
  2. 配置包含头文件目录和库目录
  3. 工程中设置链接指定的lib:fenbieshlibssl.lib,libcrypto.lib
  4. 将对应的dll拷贝到exe执行目录:libcrypto-1_1.dll, libssl-1_1.dll
linux下同理

代码

  1. #include <iostream>
  2. #include <cassert>
  3. #include <string>
  4. #include <vector>
  5. #include "openssl/md5.h"
  6. #include "openssl/sha.h"
  7. #include "openssl/des.h"
  8. #include "openssl/rsa.h"
  9. #include "openssl/pem.h"
  10. // ---- md5摘要哈希 ---- //
  11. void md5(const std::string &srcStr, std::string &encodedStr, std::string &encodedHexStr)
  12. {
  13. // 调用md5哈希
  14. unsigned char mdStr[33] = {0};
  15. MD5((const unsigned char *)srcStr.c_str(), srcStr.length(), mdStr);
  16. // 哈希后的字符串
  17. encodedStr = std::string((const char *)mdStr);
  18. // 哈希后的十六进制串 32字节
  19. char buf[65] = {0};
  20. char tmp[3] = {0};
  21. for (int i = 0; i < 32; i++)
  22. {
  23. sprintf(tmp, "%02x", mdStr[i]);
  24. strcat(buf, tmp);
  25. }
  26. buf[32] = '\0'; // 后面都是0,从32字节截断
  27. encodedHexStr = std::string(buf);
  28. }
  29. // ---- sha256摘要哈希 ---- //
  30. void sha256(const std::string &srcStr, std::string &encodedStr, std::string &encodedHexStr)
  31. {
  32. // 调用sha256哈希
  33. unsigned char mdStr[33] = {0};
  34. SHA256((const unsigned char *)srcStr.c_str(), srcStr.length(), mdStr);
  35. // 哈希后的字符串
  36. encodedStr = std::string((const char *)mdStr);
  37. // 哈希后的十六进制串 32字节
  38. char buf[65] = {0};
  39. char tmp[3] = {0};
  40. for (int i = 0; i < 32; i++)
  41. {
  42. sprintf(tmp, "%02x", mdStr[i]);
  43. strcat(buf, tmp);
  44. }
  45. buf[32] = '\0'; // 后面都是0,从32字节截断
  46. encodedHexStr = std::string(buf);
  47. }
  48. // ---- des对称加解密 ---- //
  49. // 加密 ecb模式
  50. std::string des_encrypt(const std::string &clearText, const std::string &key)
  51. {
  52. std::string cipherText; // 密文
  53. DES_cblock keyEncrypt;
  54. memset(keyEncrypt, 0, 8);
  55. // 构造补齐后的密钥
  56. if (key.length() <= 8)
  57. memcpy(keyEncrypt, key.c_str(), key.length());
  58. else
  59. memcpy(keyEncrypt, key.c_str(), 8);
  60. // 密钥置换
  61. DES_key_schedule keySchedule;
  62. DES_set_key_unchecked(&keyEncrypt, &keySchedule);
  63. // 循环加密,每8字节一次
  64. const_DES_cblock inputText;
  65. DES_cblock outputText;
  66. std::vector<unsigned char> vecCiphertext;
  67. unsigned char tmp[8];
  68. for (int i = 0; i < clearText.length() / 8; i++)
  69. {
  70. memcpy(inputText, clearText.c_str() + i * 8, 8);
  71. DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_ENCRYPT);
  72. memcpy(tmp, outputText, 8);
  73. for (int j = 0; j < 8; j++)
  74. vecCiphertext.push_back(tmp[j]);
  75. }
  76. if (clearText.length() % 8 != 0)
  77. {
  78. int tmp1 = clearText.length() / 8 * 8;
  79. int tmp2 = clearText.length() - tmp1;
  80. memset(inputText, 0, 8);
  81. memcpy(inputText, clearText.c_str() + tmp1, tmp2);
  82. // 加密函数
  83. DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_ENCRYPT);
  84. memcpy(tmp, outputText, 8);
  85. for (int j = 0; j < 8; j++)
  86. vecCiphertext.push_back(tmp[j]);
  87. }
  88. cipherText.clear();
  89. cipherText.assign(vecCiphertext.begin(), vecCiphertext.end());
  90. return cipherText;
  91. }
  92. // 解密 ecb模式
  93. std::string des_decrypt(const std::string &cipherText, const std::string &key)
  94. {
  95. std::string clearText; // 明文
  96. DES_cblock keyEncrypt;
  97. memset(keyEncrypt, 0, 8);
  98. if (key.length() <= 8)
  99. memcpy(keyEncrypt, key.c_str(), key.length());
  100. else
  101. memcpy(keyEncrypt, key.c_str(), 8);
  102. DES_key_schedule keySchedule;
  103. DES_set_key_unchecked(&keyEncrypt, &keySchedule);
  104. const_DES_cblock inputText;
  105. DES_cblock outputText;
  106. std::vector<unsigned char> vecCleartext;
  107. unsigned char tmp[8];
  108. for (int i = 0; i < cipherText.length() / 8; i++)
  109. {
  110. memcpy(inputText, cipherText.c_str() + i * 8, 8);
  111. DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_DECRYPT);
  112. memcpy(tmp, outputText, 8);
  113. for (int j = 0; j < 8; j++)
  114. vecCleartext.push_back(tmp[j]);
  115. }
  116. if (cipherText.length() % 8 != 0)
  117. {
  118. int tmp1 = cipherText.length() / 8 * 8;
  119. int tmp2 = cipherText.length() - tmp1;
  120. memset(inputText, 0, 8);
  121. memcpy(inputText, cipherText.c_str() + tmp1, tmp2);
  122. // 解密函数
  123. DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_DECRYPT);
  124. memcpy(tmp, outputText, 8);
  125. for (int j = 0; j < 8; j++)
  126. vecCleartext.push_back(tmp[j]);
  127. }
  128. clearText.clear();
  129. clearText.assign(vecCleartext.begin(), vecCleartext.end());
  130. return clearText;
  131. }
  132. // ---- rsa非对称加解密 ---- //
  133. #define KEY_LENGTH  2048               // 密钥长度
  134. #define PUB_KEY_FILE "pubkey.pem"    // 公钥路径
  135. #define PRI_KEY_FILE "prikey.pem"    // 私钥路径
  136. // 函数方法生成密钥对
  137. void generateRSAKey(std::string strKey[2])
  138. {
  139. // 公私密钥对
  140. size_t pri_len;
  141. size_t pub_len;
  142. char *pri_key = NULL;
  143. char *pub_key = NULL;
  144. // 生成密钥对
  145. RSA *keypair = RSA_generate_key(KEY_LENGTH, RSA_3, NULL, NULL);
  146. BIO *pri = BIO_new(BIO_s_mem());
  147. BIO *pub = BIO_new(BIO_s_mem());
  148. PEM_write_bio_RSAPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL);
  149. PEM_write_bio_RSAPublicKey(pub, keypair);
  150. // 获取长度
  151. pri_len = BIO_pending(pri);
  152. pub_len = BIO_pending(pub);
  153. // 密钥对读取到字符串
  154. pri_key = (char *)malloc(pri_len + 1);
  155. pub_key = (char *)malloc(pub_len + 1);
  156. BIO_read(pri, pri_key, pri_len);
  157. BIO_read(pub, pub_key, pub_len);
  158. pri_key[pri_len] = '\0';
  159. pub_key[pub_len] = '\0';
  160. // 存储密钥对
  161. strKey[0] = pub_key;
  162. strKey[1] = pri_key;
  163. // 存储到磁盘(这种方式存储的是begin rsa public key/ begin rsa private key开头的)
  164. FILE *pubFile = fopen(PUB_KEY_FILE, "w");
  165. if (pubFile == NULL)
  166. {
  167. assert(false);
  168. return;
  169. }
  170. fputs(pub_key, pubFile);
  171. fclose(pubFile);
  172. FILE *priFile = fopen(PRI_KEY_FILE, "w");
  173. if (priFile == NULL)
  174. {
  175. assert(false);
  176. return;
  177. }
  178. fputs(pri_key, priFile);
  179. fclose(priFile);
  180. // 内存释放
  181. RSA_free(keypair);
  182. BIO_free_all(pub);
  183. BIO_free_all(pri);
  184. free(pri_key);
  185. free(pub_key);
  186. }
  187. // 命令行方法生成公私钥对(begin public key/ begin private key)
  188. // 找到openssl命令行工具,运行以下
  189. // openssl genrsa -out prikey.pem 1024
  190. // openssl rsa - in privkey.pem - pubout - out pubkey.pem
  191. // 公钥加密
  192. std::string rsa_pub_encrypt(const std::string &clearText, const std::string &pubKey)
  193. {
  194. std::string strRet;
  195. RSA *rsa = NULL;
  196. BIO *keybio = BIO_new_mem_buf((unsigned char *)pubKey.c_str(), -1);
  197. // 此处有三种方法
  198. // 1, 读取内存里生成的密钥对,再从内存生成rsa
  199. // 2, 读取磁盘里生成的密钥对文本文件,在从内存生成rsa
  200. // 3,直接从读取文件指针生成rsa
  201. RSA* pRSAPublicKey = RSA_new();
  202. rsa = PEM_read_bio_RSAPublicKey(keybio, &rsa, NULL, NULL);
  203. int len = RSA_size(rsa);
  204. char *encryptedText = (char *)malloc(len + 1);
  205. memset(encryptedText, 0, len + 1);
  206. // 加密函数
  207. int ret = RSA_public_encrypt(clearText.length(), (const unsigned char*)clearText.c_str(), (unsigned char*)encryptedText, rsa, RSA_PKCS1_PADDING);
  208. if (ret >= 0)
  209. strRet = std::string(encryptedText, ret);
  210. // 释放内存
  211. free(encryptedText);
  212. BIO_free_all(keybio);
  213. RSA_free(rsa);
  214. return strRet;
  215. }
  216. // 私钥解密
  217. std::string rsa_pri_decrypt(const std::string &cipherText, const std::string &priKey)
  218. {
  219. std::string strRet;
  220. RSA *rsa = RSA_new();
  221. BIO *keybio;
  222. keybio = BIO_new_mem_buf((unsigned char *)priKey.c_str(), -1);
  223. // 此处有三种方法
  224. // 1, 读取内存里生成的密钥对,再从内存生成rsa
  225. // 2, 读取磁盘里生成的密钥对文本文件,在从内存生成rsa
  226. // 3,直接从读取文件指针生成rsa
  227. rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);
  228. int len = RSA_size(rsa);
  229. char *decryptedText = (char *)malloc(len + 1);
  230. memset(decryptedText, 0, len + 1);
  231. // 解密函数
  232. int ret = RSA_private_decrypt(cipherText.length(), (const unsigned char*)cipherText.c_str(), (unsigned char*)decryptedText, rsa, RSA_PKCS1_PADDING);
  233. if (ret >= 0)
  234. strRet = std::string(decryptedText, ret);
  235. // 释放内存
  236. free(decryptedText);
  237. BIO_free_all(keybio);
  238. RSA_free(rsa);
  239. return strRet;
  240. }
  241. int main(int argc, char **argv)
  242. {
  243. // 原始明文
  244. std::string srcText = "this is an example";
  245. std::string encryptText;
  246. std::string encryptHexText;
  247. std::string decryptText;
  248. std::cout << "=== 原始明文 ===" << std::endl;
  249. std::cout << srcText << std::endl;
  250. // md5
  251. std::cout << "=== md5哈希 ===" << std::endl;
  252. md5(srcText, encryptText, encryptHexText);
  253. std::cout << "摘要字符: " << encryptText << std::endl;
  254. std::cout << "摘要串: " << encryptHexText << std::endl;
  255. // sha256
  256. std::cout << "=== sha256哈希 ===" << std::endl;
  257. sha256(srcText, encryptText, encryptHexText);
  258. std::cout << "摘要字符: " << encryptText << std::endl;
  259. std::cout << "摘要串: " << encryptHexText << std::endl;
  260. // des
  261. std::cout << "=== des加解密 ===" << std::endl;
  262. std::string desKey = "12345";
  263. encryptText = des_encrypt(srcText, desKey);
  264. std::cout << "加密字符: " << std::endl;
  265. std::cout << encryptText << std::endl;
  266. decryptText = des_decrypt(encryptText, desKey);
  267. std::cout << "解密字符: " << std::endl;
  268. std::cout << decryptText << std::endl;
  269. // rsa
  270. std::cout << "=== rsa加解密 ===" << std::endl;
  271. std::string key[2];
  272. generateRSAKey(key);
  273. std::cout << "公钥: " << std::endl;
  274. std::cout << key[0] << std::endl;
  275. std::cout << "私钥: " << std::endl;
  276. std::cout << key[1] << std::endl;
  277. encryptText = rsa_pub_encrypt(srcText, key[0]);
  278. std::cout << "加密字符: " << std::endl;
  279. std::cout << encryptText << std::endl;
  280. decryptText = rsa_pri_decrypt(encryptText, key[1]);
  281. std::cout << "解密字符: " << std::endl;
  282. std::cout << decryptText << std::endl;
  283. system("pause");
  284. return 0;
  285. }

运行结果

  1. === 原始明文 ===
  2. this is an example
  3. === md5哈希 ===
  4. 摘要字符: 乵驥!範
  5. 摘要串: 9202816dabaaf34bb106a10421b9a0d0
  6. === sha256哈希 ===
  7. 摘要字符: 訪X5衽鄁媫j/醢?17?P?4膡zD
  8. 摘要串: d44c035835f1c5e0668b7d186a2ff5b0
  9. === des加解密 ===
  10. 加密字符:
  11. ?/灲取鮋t8:夽U錺?说
  12. 解密字符:
  13. this is an example
  14. === rsa加解密 ===
  15. 公钥:
  16. -----BEGIN RSA PUBLIC KEY-----
  17. MIIBCAKCAQEA59WESdYbPsD6cYATooC4ebClTpvbTsu3X29Ha0g31kW3AmLR2zLj
  18. hMvdWjUhhVuM7xBoh3Ufoyj4jTGHVhunFfbzxNrt1Nb64N95bZH8e9u6LjJYqh4e
  19. sNoFknG+McjoSLNqGW9Yd8ejKH1Ju6C9SBUcC43XbB3XdC2matgV1zTsKhqjuywm
  20. gVN9DZdo2TlZkqsvOHC23rbQ+lP09rpQJ/RI4NQSnCUBqQxErCN85trcWRj1zyJA
  21. WaBZSvKh7J5RJcrC2ByMDmL7jrDDZl7YEolyW93SSc4xTE9Dr20OXznXNDsfQc9r
  22. RQHBri8Aqsu4WW3tHSBRmjW5kxFMxS4qxwIBAw==
  23. -----END RSA PUBLIC KEY-----
  24. 私钥:
  25. -----BEGIN RSA PRIVATE KEY-----
  26. MIIEowIBAAKCAQEA59WESdYbPsD6cYATooC4ebClTpvbTsu3X29Ha0g31kW3AmLR
  27. 2zLjhMvdWjUhhVuM7xBoh3Ufoyj4jTGHVhunFfbzxNrt1Nb64N95bZH8e9u6LjJY
  28. qh4esNoFknG+McjoSLNqGW9Yd8ejKH1Ju6C9SBUcC43XbB3XdC2matgV1zTsKhqj
  29. uywmgVN9DZdo2TlZkqsvOHC23rbQ+lP09rpQJ/RI4NQSnCUBqQxErCN85trcWRj1
  30. zyJAWaBZSvKh7J5RJcrC2ByMDmL7jrDDZl7YEolyW93SSc4xTE9Dr20OXznXNDsf
  31. Qc9rRQHBri8Aqsu4WW3tHSBRmjW5kxFMxS4qxwIBAwKCAQEAmo5YMTlnfytRoQAN
  32. FwB6+8sY3xKSNIfPlPTaR4V6jtkkrEHhPMyXrd0+PCNrrj0In2BFr6NqbMX7CMuv
  33. jr0aDqSigzyejeSnQJT7nmFS/T0myXblxr6/IJFZDEvUITCa2yJGu5+QT9psxajb
  34. 0mso2ri9XQk6SBPk+B5u8eVj5Myt4tqpWL0DEEDzwfhihs+uEGM7g6bPvQBI4JXu
  35. 8uxfSRUkpyZ5s1koEhqj+RCguksPzSWO/Ut2Sd60iOUMRhya2aEbAyRTtfhsXja3
  36. 4NMWjXorJ0SRkryM1iLJvVWkhkcr2vShH9rm9qz16BkrkI9/9Yx++GNNr6VU/p/+
  37. Waa8CwKBgQD4m0ryXi6rCqazdCICGoZJGzaljApOZ1rWOiotM9TekaYE7tZ2NDAT
  38. eytiCzxvs4/+1Jt5XzdGJ035VJKSai/n2ZzAq1YYtVHy5CG2olmeFtwaIWU18m2s
  39. RjHQf/FiscVB4XdKrHjh3gLgSB8MWMDg/krisxT86HNyp1UE2jZv+QKBgQDuuoez
  40. V+H23ktb9oDS9HuLXt+wZuww29uNb0jhVoLiqK6M90Pl2u8yErjsq04cG9pF0MUl
  41. 8/nIw4RRKQh9GUOBBbxZqA/1yBxmHTz48siYJ3YXf5HB+0WxxOlEk3s05AnTilTi
  42. 5Y4u9Ptwieoy+TOXatBL9XZgKkpHbcxKZH2gvwKBgQClvNyhlB8cscR3osFWvFmG
  43. EiRuXVw0ROc5fBweIo3ptm6t9I75eCAM/MeWsihKd7VUjbz7lM+EGjP7jbcMRsqa
  44. kRMrHOQQeOFMmBZ5wZEUDz1mwO4j9vPILsvgVUuXIS4r66TccvtBPqyVhWoIOytA
  45. qYdBzLiomvehxONYkXmf+wKBgQCfJwUiOpaklDI9TwCMov0HlJUgRJ115+ezn4Xr
  46. jwHscHRd+i1D50ohYdCdx4loEpGD4INuoqaF162LcLBTZi0Arn2RGrVOhWhEE337
  47. TIW6xPlk/7aBUi52g0Ytt6d4mAaNBuNB7l7J+KegW/F3UM0PnIrdTk7qxtwvnogx
  48. mFPAfwKBgAEuRGqF2Q9bNu/r0OufeFxsYm0zFvWBIxbq3DxPYRtzfhiQMeTOzl1g
  49. 5rowAtb/w1SusGAZ4/lEUZoBgzV+8fr+rpx3eavVCmcXBVjDi9B5nNLIXWkcoEQG
  50. G/4ZwXUr5kyTBktL6mIBVNJ8dJUQo8xyxK0GjfWhlsk5t/Zu8tmK
  51. -----END RSA PRIVATE KEY-----
  52. 加密字符:
  53. 佷篒?z_&欗霐嗪K赸;J╄[i9?S絑?て晄p?[hD∞51鱠,k|1裡郿     犓鈪鑒?饞w2?`vlu
  54. L<萿囂?圖L潥?O0佲y▃飕E堿^桮??,e鉀煯ACsJ挈R聡-鳊帔!eQC乥+1\(齀
  55. я盈Xj饮[o6覾羂≯傁澓
  56. 解密字符:
  57. this is an example

注:

(1)在读取公钥文件时,PEM_read_RSA_PUBKEY()函数和PEM_read_RSAPublicKEY()的疑惑。有时候为什么读取私钥文件用的PEM_read_RSAPrivateKey(),针对上述openssl命令生成的公钥文件,在读取其内容时用对称的PEM_read_RSAPublicKEY()接口却会报错,必须要用PEM_read_RSA_PUBKEY()才可以。

RSA PUBLIC KEY和PUBLIC KEY的两种公钥文件其存储方式是不一样的,PEM_read_RSAPublicKEY()只能读取RSA PUBLIC KEY开头形式的公钥文件(用函数生成的);而PEM_read_RSA_PUBKEY()只能读取PUBLIC KEY开头格式的公钥文件(用命令行生成),所以公钥私钥读取函数一定要跟生成的密钥对的格式对应起来。

(2)公钥加密和私钥解密, 私钥加密公钥解密 这两种都可以使用

(3)一般加密之后的字符串因为编码跟中文对应不上所以是乱码,在很多场合选择用十六进制串输出

(4)实际的工程应用中读取密钥对需要加安全验证

(5)用纯代码不依赖openssl库也是可以自己实现这些加解密算法的,搞清楚原理就行

http://blog.csdn.net/u012234115/article/details/72762045

C/C++使用openssl进行摘要和加密解密(md5, sha256, des, rsa)的更多相关文章

  1. php中des加密解密 匹配C#des加密解密 对称加密

    原文:php中des加密解密 匹配C#des加密解密 对称加密 网上找来的 php des加密解密 完全匹配上一篇C# 字符串加密解密函数  可以用于C#和php通信 对数据进行加密,其中$key 是 ...

  2. ruby的加密方法整理(des rsa加密 加签)

    # coding:utf-8require 'openssl'require 'base64'#des加密并且base64编码def des_encrypt des_key, des_text des ...

  3. 支付接口中常用的加密解密以及验签rsa,md5,sha

    一.常用加密类型分类 1.对称加密:采用单钥对信息进行加密和解密,即同一个秘钥既可以对信息进行加密,也可以进行解密.此类型称之为对称加密.特点速度快,常用于对大量数据信息或文件加密时使用.常用例子:D ...

  4. DES加密解密 MD5加密解密

    #region MD5 加密 /// <summary> /// MD5加密静态方法 /// </summary> /// <param name="Encry ...

  5. VB使用API进行RC4加密解密(MD5密钥)

    根据网络资料整改,来源未知,已调试通过. Option Explicit Private Declare Function CryptAcquireContext Lib "advapi32 ...

  6. 工作中拓展的加密解密传输方式. DES对称加密传输.

    系统间通过xml传输, 不能采用明文, 就加密传输. 秘钥(真正有效的是前8位)存储于配置中. public static string EncryptStr(this string content, ...

  7. C# 加密解密以及sha256不可逆加密案例

    class Program { static void Main(string[] args) { string aa = "身份证"; string bb = "key ...

  8. [C#]加密解密 MD5、AES

    /// <summary> /// MD5函数 /// </summary> /// <param name="str">原始字符串</p ...

  9. openssl evp RSA 加密解密

    openssl evp RSA 加密解密 可以直接使用RSA.h 提供的接口 如下测试使用EVP提供的RSA接口 1. EVP提供的RSA 加密解密 主要接口: int EVP_PKEY_encryp ...

随机推荐

  1. poi读取excell表格

    原文链接:http://blog.csdn.net/qq_37936542/article/details/79024847 最近项目需要实现一个将excell中的数据导入数据库,在网上找到这篇文章, ...

  2. [tmux] Share a tmux session for pair programming with ssh

    By using ssh, you can share a tmux session, making pair programming much easier. We'll learn how to ...

  3. html5-3 html5标签(热点地图如何实现)(边学边做)

    html5-3 html5标签(热点地图如何实现)(边学边做) 一.总结 一句话总结:热点地图用绝对定位实现. 1.自定义列表怎么弄? dl  自定义列表dt  自定义标题dd  自定义列表内容 2. ...

  4. 【t042】炮击坦克

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 在一个坐标轴上,有M辆坦克,第i辆坦克在时刻0处于pos[i](pos[i]>0),speed[ ...

  5. 代码在线执行工具(PHP,Java,C++ 等)

    http://www.it1352.com/Onlinetools 支持几十种语言的在线运行. 缺点:对请求频率限制太严格了,一分钟不到十次吧...可以清理浏览器 Cookie 之后重新访问.必须用示 ...

  6. 接入Erlang控制台的几种方法

    在window中调试的时候我们可以通过启动多个cmd窗口运行Erlang节点,在生产环境中我们需要Erlang服务在Centos服务器上后台运行;这就需要在启动的时候添加启动参数detached来脱离 ...

  7. 【a802】最少转弯问题

    Time Limit: 10 second Memory Limit: 2 MB 问题描述 给出一张地图,这张地图被分为n*m(n,m<=100)个方块,任何一个方块不是平地就是高山.平地可以通 ...

  8. java.lang.ExceptionInInitializerError异常分析

    今天在项目开发时遇到一个问题,整个项目是使用Spring等框架搭建起来的在运行项目时不报任何的异常信息,就是找不到某个类信息,各方查找该类确实是存在的,最后通过断点跟踪时在异常栈内发现java.lan ...

  9. WPF窗口继承实现统一风格的自定义窗口

    如何实现一个窗口的风格(style),让所有的窗口都继承这样同样的风格,包括标题栏,放大.缩小和关闭按钮. 那么,我们可不可以就建立一个Base窗口,然后将这个窗口的风格给设计好之后,所有的窗口都继承 ...

  10. 停止学习Wireshark

    下载和安装好Wireshark之后,启动Wireshark而且在接口列表中选择接口名,然后開始在此接口上抓包.比如.假设想要在无线网络上抓取流量,点击无线接口.点击Capture Options能够配 ...