c/c++

Java AES算法和openssl配对

陌路散爱 提交于 2020-02-29 10:50:41
近日工作上的原因,需要实现Java AES算法和C语言下基于openssl的AES 算法通信。这是个老问题了,网上搜到不少资料,但都不是很详细,没能解决问题。只能自己来了。 先说说AES算法。AES算法的实现有四种,如CBC/ECB/CFB/OFB,这四种Java和C都有实现。AES算法还有末尾的填充(padding),java支持的padding方式有三种NoPadding/PKCS5Padding/,而C却不能显式的设置padding方式,默认的padding就是在末尾加 '\0'。这是一个大坑,多少人都坑在这了。另外,网上很多JAVA AES算法,很多都用SecureRandom,如果你的代码中出现了SecureRandom这个东西,那么你再也不能用C解出来了。 先说Java端的。从良心上说,java的封装比C要强多了。先上代码: public static String encrypt(String content, String passwd) { try { Cipher aesECB = Cipher.getInstance("AES/ECB/PKCS5Padding"); SecretKeySpec key = new SecretKeySpec(passwd.getBytes(), "AES"); aesECB.init(Cipher.ENCRYPT_MODE,

C/C++左值性精髓(二)哪些表达式是左值,哪些是右值?-----左值表达式

你离开我真会死。 提交于 2020-02-29 05:54:19
左值具有对象或不完整类型,在C++中还具有函数或引用类型,但是,并非具有上述类型的表达式就是左值,关键是左值必须指示一个对象,无论该对象有效或无效、完整或不完整,在C++中则包含非静态成员函数之外的函数。例如: int i; int *p = &i; i和p都指示一个对象,且具有对象类型,因而都是左值,而&i虽然具有对象类型,但由于没有指示一个对象,因此不是左值。 不完整类型也可以成为左值,因为不完整类型本质其实与对象类型一样,只不过尚未有完整的对象信息。前向声明是我们最常用的不完整类型,对前向声明的引用是允许的,例如: extern struct S s; S & r = s; 虽然s的完整定义尚未可见,但仍可以作为左值初始化左值引用。 来源: oschina 链接: https://my.oschina.net/u/154959/blog/56311

C/C++左值性精髓(二)哪些表达式是左值,哪些是右值?--- 函数调用表达式和强制转换

房东的猫 提交于 2020-02-29 05:54:08
对于函数调用表达式和强制转换表达式的结果,在C中都属于右值;C++由于增加了引用类型,结果为引用的函数调用表达式和强制转换表达式都属于左值,示例如下: int& fun1( int & r ){ return r; } int fun2( void ){ return 10; } int i = 20; fun2( ) = 30; //A cout << ( fun1( i ) = 30 ); //B ( int & )10 = 20; //C ( const int & )10 = 20; //D ( int & )i = 40; //E ( double & )i = 50; //F cout << ( double & )i; //G A: fun2的返回值是一个右值,不能作为内置赋值表达式的左操作数,因此A是错误的; B: fun1返回一个引用,属于左值,因此可以作为内置赋值运算符的左操作数; C: C试图将一个右值强制转换为引用,但是,只有const引用才能引用一个右值,因此错 误; D: D比C进步了一点,强制转换为const引用,但仍然是错误的,因为const引用属于不可修改的左值,不能通过const引用修改其引用的对象; E: E将一个int变量强制转换为int引用并被修改。这个表达式容易出现误解,以为i被临时转换为一个引用,其实不然,( int&

C/C++左值性精髓(二)哪些表达式是左值,哪些是右值?----右值表达式

陌路散爱 提交于 2020-02-29 05:53:56
C对于右值的定义是表达式的值,C中所有完整表达式的结果都是右值。所谓完整表达式(full expression),指的是这样的表达式,它不是其它表达式或声明符的一部分。包括条件表达式和逗号表达式等等都不产生左值,而子表达式计算产生的中间结果或临时对象,很多人以为都是右值,但实际上,它们不一定是右值。例如: int a[ 5 ] = { 1, 2, 3, 4, 5 }; int *p = a; *p = 2; /* A */ a[ 1 ] = 3; /* B */ *p; /* C */ a[ 1 ]; /* D */ A和B中的*p和a[ 1 ]都是内置赋值运算符的子表达式,虽然都是中间结果,但显然都属于左值表达式;只有当它们作为完整表达式时,如C和D中的*p和a[ 1 ]所示,都会进行最后的左值转换,使得结果皆为右值。这个现象的本质,是由于C将所有完整表达式的结果一律进行最后的从左值到右值的转换,这个行为可以理解为一个完全求值的过程(完全求值不是标准术语)。 但C++的完整表达式并不要求进行完全求值,是否保留左值性视需要而定,这个“需要”是什么?其实是C++某些运算符的强制规定,例如内置赋值运算符、前置增量和前置减量运算符等等,这类运算符的结果被强制规定为左值,对于条件运算符,只有第二和第三表达式皆为左值且类型相同时才保证结果为左值。原因无它,仅仅规定而已。 右值是不是对象

C/C++左值性精髓(二)哪些表达式是左值,哪些是右值?----后缀表达式

偶尔善良 提交于 2020-02-29 05:08:17
在表达式的左值性中,后缀表达式是比较复杂的一种情况。后缀表达式有很多种,这里讨论的是E1.E2和E1->E2形式的后缀表达式。 4.1 E1.E2形式的后缀表达式 若E2为静态数据成员或引用数据成员,无论E1的左值性如何,E1.E2的结果都是左值;若E2为非静态非引用数据成员,C和C++标准都规定如果E1为左值,则E1.E2也是左值;当E1为右值时,从原理上说,右值对象的一部分也应该是一个右值,因此在C中,无论E2的左值性如何,E1.E2皆为右值;那么C++中的结果又如何呢?按道理应该顺理成章也为右值吧,但令人惊讶的是,C++98和C++2003都没有对此作出规定!因此在C++98和C++2003中,无论编译器将这种情况作为左值或右值都没有违反标准。这种情况显然是一个漏洞,在C++新标准C++11的制定过程中,WG21的专家在其Defect Reports中承认了这一点,并在C++11中将结果修正为一个prvalue(pure rvalue,纯右值)。 struct A { A( int& i ) : r( i ){} static int k; int &r; int j; }; int A::k = 10; A foo( int& r ){ A a( r ); return A; } ...... int i = 20; A a( i ); a.k = 30; //静态成员

cannot convert ‘a’ (type ‘int’) to type ‘int&&’

老子叫甜甜 提交于 2020-02-29 04:58:37
背景 启用C++11编译老代码的时候,g++报错。示例代码如下: #include <utility> int main() { int a = 0; auto b = std::make_pair<int, int>(a, 1); return 0; } 出错信息: test.cpp: In function ‘int main()’: test.cpp:5:41: error: no matching function for call to ‘make_pair(int&, int)’ auto b = std::make_pair<int, int>(a, 1); ^ test.cpp:5:41: note: candidate is: In file included from /usr/include/c++/4.8/utility:70:0, from test.cpp:1: /usr/include/c++/4.8/bits/stl_pair.h:276:5: note: template<class _T1, class _T2> constexpr std::pair<typename std::__decay_and_strip<_Tp>::__type, typename std::__decay_and_strip<_T2>::__type> std:

C/C++程序员应聘常见面试题深入剖析

邮差的信 提交于 2019-12-20 03:34:58
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> C/C++程序员应聘常见面试题深入剖析 1.引言   本文的写作目的并不在于提供C/C++程序员求职面试指导,而旨在从技术上分析面试题的内涵。文中的大多数面试题来自各大论坛,部分试题解答也参考了网友的意见。  许多面试题看似简单,却需要深厚的基本功才能给出完美的解答。企业要求面试者写一个最简单的strcpy函数都可看出面试者在技术上究竟达到了怎样的程 度,我们能真正写好一个strcpy函数吗?我们都觉得自己能,可是我们写出的strcpy很可能只能拿到10分中的2分。读者可从本文看到strcpy 函数从2分到10分解答的例子,看看自己属于什么样的层次。此外,还有一些面试题考查面试者敏捷的思维能力。   分析这些面试题,本身包含很强的趣味性;而作为一名研发人员,通过对这些面试题的深入剖析则可进一步增强自身的内功。 2.找错题   试题1: void test1() {   char string[10];   char* str1 = "0123456789";   strcpy( string, str1 ); }   试题2: void test2() {   char string[10], str1[10];   int i;   for(i=0; i<10; i++)   {    str1 = 'a'

【日积月累】C/C++可变参数函数的实现

社会主义新天地 提交于 2019-12-12 12:52:33
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 1 、可变参函数的原理 C / C++函数的参数是存放在栈区的,并且参数的入栈是从参数的右边开始,即最后一个参数先入栈,而第一个参数最后才入栈,所以,根据栈的后进先出性质,函数总能找到第一个参数。所以,可变参函数的实现必须能够从已知参数中获取到函数所需要参数的个数; 例如printf函数,第一个参数就是一个格式串,而后面所需要的参数个数能够从格式串中得到。 2 、可变参函数的设计 标准头文件s tdar g .h 提供了一套对可变参函数的实现机制,所以编写可变参函数需要包含该头文件。 # include <stdarg.h> C 中变长实参头文件 stdarg.h 提供了一个数据类型 va-list 和三个宏( va-start 、 va-arg 和 va-end ),用它们在被调用函数不知道参数个数和类型时对可变参数表进行测试,从而为访问可变参数提供了方便且有效的方法。 va-list 是一个 char 类型的指针,当被调用函数使用一个可变参数时,它声明一个类型为 va-list 的变量,该变量用来指向 va-arg 和 va-end 所需信息的位置。 VC++中va_list、va_start、va_arg、va_end的细节: va_list: typedef char * va_list; va

Notepad++配置C/C++IDE(详细)

谁都会走 提交于 2019-12-10 17:30:28
一、先前准备 <br/>1、notepad++ <br/>2、配置一个C/C++的IDE必备的是GNU的GCC(用于编译)和GDB(用于调试)。在Windows下,我们可以下载安装MinGW,这里默认就提供了GCC和GDB 二、参数配置 <p>1、将MinGW下的bin目录放置在path目录下,让用户在cmd命令模式中可以直接调用g++/gcc和gdb命令。 具体如下: 计算机-》属性-》高级系统设置-》环境变量-》系统变量(用户变量也行):path 中添加D:\MinGW\bin;(作者是安装在D盘下)</p> <p>2、notepad++能作为IDE的原理主要就是通过notepad++内置的命令执行器,去执行g++/g++和gdb命令,从而完成编译,调试,运行等功能,接下来介绍命令执行器中的一些命令 </p> 1、cmd表示在cmd命令窗口中执行命令<br/> 2、/k是cmd的参数,表示将后面的字符串作为命令执行<br/> 3、$(FULL_CURRENT_PATH):是notepad++的参数,表示当前打开文件的全路径(这里是指代码文件,c:\main.c)<br/> 4、$(NAME_PART):是notepad++的参数,表示当前打开文件的去掉后缀名的文件名,比如main.c中的main<br/> 5、G++的命令 g++ proj.cc:默认产生a.exe可执行文件

【网络编程】大端模式和小端模式(大头序和小头序)

≡放荡痞女 提交于 2019-12-07 11:09:15
大端:多字节值的大端存储在该值的起始位置;(老大站排头为大) 小端:多字节值的小端存储在该值的起始位置;(老小站排头为小) 例如16bit整数:0x0102,其中01即为多字节值的大端,02即为多字节值的小端。 在网络中传输的都是大端序,但具体到某台主机CPU的实现,则有可能是大端序也可能是小端序。一般X86是小端。 那么,如何通过程序来判断当前主机到底是大端还是小端呢? /*判断大端还是小端, 1:小端 0:大端*/ int GetEndian() { union { int a; char b; } s; s.a = 0x0001; return (1 == s.b); } 联合体union的存放顺序是所有成员都从低地址开始存放,给s.a赋值为0x01,00为a的高端,01为a的低端,如果b==1,即a的低端位于起始位置,即小端,反之为大端。 我觉得《UNIX网络编程》(第一卷)给的例子更严密一些: /*判断大端还是小端, 1:小端 0:大端*/ int GetEndian() { union { short s; char c[sizeof(short)]; }un; un.s = 0x0102; if(2 == sizeof(short)) { if(1 == un.c[0] && 2 == un.c[1]) { printf("big-endian\n"); return