C估计是最普及的,几乎写代码都会抡两行出来,一听说写C写了240个月,那就得当面磕头,我还真见过时间越长代码越烂的(这个和英语4级是一样,大一过4级最容易,大四几乎很难过,因为从高中毕业就开始退化),所以我要说,好的代码和年纪没有关系,有些人就是好,有些人就是差,而且永远都不会长进。
对比下一个程序,从RSA的公钥里面取出公钥来,打印出来,这个其实就没啥功能,也能看出来水平高低?是的。
#include <string.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
static EVP_PKEY *__load_pubkey(BIO *err, const char *file, const char *key_descrip)
{
BIO *key = NULL;
EVP_PKEY *pkey = NULL;
key = BIO_new(BIO_s_file());
if (key == NULL) {
ERR_print_errors(err);
goto end;
}
if (BIO_read_filename(key, file) <= 0) {
BIO_printf(err, "Error opening %s %s\n", key_descrip, file);
ERR_print_errors(err);
goto end;
}
pkey = PEM_read_bio_PUBKEY(key, NULL, NULL, NULL);
end:
if (key != NULL)
BIO_free(key);
if (pkey == NULL)
BIO_printf(err, "unable to load %s\n", file);
return (pkey);
}
int main(void)
{
RSA *rsa = NULL;
EVP_PKEY *pkey = NULL;
BIO *bio_err = NULL;
BIO *bio_out = BIO_new_fp(stdout, BIO_NOCLOSE);
char *modulus_string, *exponent_string;
int i;
bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
pkey = __load_pubkey(bio_err, "./pub.key", "Public Key");
if (pkey == NULL)
return -1;
rsa = EVP_PKEY_get1_RSA(pkey);
EVP_PKEY_free(pkey);
modulus_string = BN_bn2hex(rsa->n);
exponent_string = BN_bn2hex(rsa->e);
BIO_printf(bio_out, "#define CHNVIDEO_PUBLIC_MODULUS_ARRAY {");
for (i = 0; i < strlen(modulus_string); i++) {
BIO_printf(bio_out, "0x%X,", modulus_string[i] + 0x80);
}
BIO_printf(bio_out, "}\n");
//BIO_printf(bio_out, "#define CHNVIDEO_PUBLIC_MODULUS \"%s\"\n", modulus_string);
BIO_printf(bio_out, "#define CHNVIDEO_PUBLIC_EXPONENT \"%s\"\n", exponent_string);
if (bio_err)
BIO_free(bio_err);
BIO_free(bio_out);
return 0;
}
看另外一个:
#include <string.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
struct RsaCleaner
{
BIO* out;
BIO* err;
BIO* key;
EVP_PKEY* pkey;
RSA* rsa;
RsaCleaner() {
out = err = key = NULL;
pkey = NULL;
}
virtual ~RsaCleaner() {
if (out) {
BIO_free(out);
}
if (err) {
BIO_free(err);
}
if (key) {
BIO_free(key);
}
if (pkey) {
EVP_PKEY_free(pkey);
}
}
};
int main(int argc, char** argv)
{
RsaCleaner rc;
rc.out = BIO_new_fp(stdout, BIO_NOCLOSE);
rc.err = BIO_new_fp(stderr, BIO_NOCLOSE);
rc.key = BIO_new(BIO_s_file());
if (!rc.key) {
BIO_printf(rc.err, "Create pub key failed: ");
ERR_print_errors(rc.err);
return -1;
}
const char* file = "./objs/license/pub.key";
if (BIO_read_filename(rc.key, file) <= 0) {
BIO_printf(rc.err, "Open pub key file %s failed: ", file);
ERR_print_errors(rc.err);
return -1;
}
rc.pkey = PEM_read_bio_PUBKEY(rc.key, NULL, NULL, NULL);
if (!rc.pkey) {
BIO_printf(rc.err, "Read pub key from %s failed.\n", file);
return -1;
}
rc.rsa = EVP_PKEY_get1_RSA(rc.pkey);
char* modulus = BN_bn2hex(rc.rsa->n);
char* exponent = BN_bn2hex(rc.rsa->e);
// output the header file.
BIO_printf(rc.out, "// this file is auto generated\n"
"#ifndef AUTO_LICENSE_HPP\n#define AUTO_LICENSE_HPP\n\n");
BIO_printf(rc.out, "#ifndef MODULUS\n #define MODULUS {");
for (char* p = modulus; *p; p++) {
if (((p - modulus) % 16) == 0) {
BIO_printf(rc.out, "\\\n ");
}
BIO_printf(rc.out, "%#x, ", p[0]);
}
BIO_printf(rc.out, "\\\n }\n#endif\n");
BIO_printf(rc.out, "#ifndef EXPONENT\n"
" #define EXPONENT \"%s\"\n#endif\n\n", exponent);
BIO_printf(rc.out, "#endif\n\n");
return 0;
}
不要说后者是C++,所以比较优美,谁傻逼谁知道,C都写得烂的人写C++更烂,这就好残疾鸟,跑都跑不动,能飞起来么?