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. 解决win7系统不支持16位实模式汇编程序DOS执行的问题

    这学期学习了汇编,在自己电脑上发现,win7的dos不支持16位实模式. 对编程来说,不能执行程序是致命的. 在经过网上搜集资料后,得到一种解决的方法--使用dosbox软件执行 dosbox简单说, ...

  2. Swift开发教程--关于Existing instance variable &#39;_delegate&#39;...的解决的方法

    xcode编译提示问题:Existing instance variable '_delegate' for property 'delegate' with  assign attribute mu ...

  3. 360随身WIFI作USB无线网卡的做法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 1. 到控制面板上把360wifi卸载. 2. 到雷凌的官网下载网卡驱动,注意选择USB(RT2870***),操作系 ...

  4. 使用JSONP解决跨域问题-代码示例

    前段时间用JSONP解决了跨域问题,现在不用了,把代码思路记下来,今后说不定还用得上. JS代码 //查询公告数据 function recentpost(){ $.getJSON(cmsUrl+&q ...

  5. [Redux] Avoid action type naming conflicts

    In redux, the action type is just a normal string type, it is easy to get naming conflicts in large ...

  6. 【codeforces 546A】Soldier and Bananas

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  7. [读书笔记]《Android开发艺术探索》第十五章笔记

    Android性能优化 Android不可能无限制的使用内存和CPU资源,过多的使用内存会导致内存溢出,即OOM. 而过多的使用CPU资源,通常是指做大量的耗时任务,会导致手机变的卡顿甚至出现程序无法 ...

  8. STL源代码学习--vector用法汇总

    一.容器vector 使用vector你必须包含头文件<vector>: #include<vector> 型别vector是一个定义于namespace std内的templ ...

  9. 使用蒲公英来发布iOS内侧版本

    1.生成ipa包 这里不介绍正规的打包方式(选择真机调试-编译成功以后-工具product-archive-....) 下面介绍快速打包方式: 1)选择真机调试-编译成功以后右击下图.app文件,选择 ...

  10. spark 基于key排序的wordcount

    java /** * 根据单词次数排序的wordcount * @author Tele * */ public class SortWordCount { private static SparkC ...