Feb6

【转载】c++中typeid与type_info

Author: leeon  Click: 7500   Comments: 0 Category: c/c++  Tag: typeid,cpp,type_info,c++

     在学习java中的Class类,有getClass方法,其特性与c++中的typeid很类似,java中调用getClass方法和c++中的typeid运算符等价。

     typeid是C++的一个关键字,其作用是在程序运行时,返回对象的类型,即所谓的RTTI(Run Time Type Identification), 它使程序能够获取由指针或引用所指向的对象的实际类型,即允许“用指向基类的指针或引用来操作对象”的程序能够获取到“这些指针或引用所指对象”的实际派生类型。在C++中,为了支持RTTI提供了两个操作符:dynamic_cast和typeid。

typeid操作符的返回结果是名为type_info的标准库类型的对象的引用。 type_info在typeinfo头文件中定义:


class type_info {public:
  virtual ~type_info();
  bool operator== (const type_info& rhs) const;
  bool operator!= (const type_info& rhs) const;
  bool before (const type_info& rhs) const;
  const char* name() const;private:
  type_info (const type_info& rhs);
  type_info& operator= (const type_info& rhs);
}; 

如下内容摘自http://www.cplusplus.com/reference/typeinfo/type_info/:


typeid can be applied to any typed expression, including a type itself, to retrieve the its type_info.

When typeid is applied to a reference or dereferenced pointer to an object of a polymorphic class type (a class declaring or inheriting a virtual function), it considers its dynamic type (i.e., the type of the most derived object). This requires the RTTI (Run-time type information) to be available.

When typeid is applied to a dereferenced null pointer a bad_typeid exception is thrown.


type_info成员介绍如下:


operator==
operator!=
Comparison operators. They return whether the two types describe the same type.
A derived type is not considered the same type as any of its base classes.
before
Returns true if the type precedes the type of rhs in the collation order.
The collation order is just an internal order kept by a particular implementation and is not necessarily related to inheritance relations or declaring order.
name
Returns a null-terminated character sequence with a human-readable name for the type.
copy constructor and copy operator
These are private, preventing type_info values from being copiable.

示例代码:

[code="cpp"]
// type_info example
#include <iostream>
#include <typeinfo>
using namespace std;

struct Base {};
struct Derived : Base {};
struct Poly_Base {virtual void Member(){}};
struct Poly_Derived: Poly_Base {};

int main() {
// built-in types:
int i;
int * pi;
cout << "int is: " << typeid(int).name() << endl;
cout << " i is: " << typeid(i).name() << endl;
cout << " pi is: " << typeid(pi).name() << endl;
cout << "*pi is: " << typeid(*pi).name() << endl << endl;

// non-polymorphic types:
Derived derived;
Base* pbase = &derived;
cout << "derived is: " << typeid(derived).name() << endl;
cout << " *pbase is: " << typeid(*pbase).name() << endl;
cout << boolalpha << "same type? ";
cout << ( typeid(derived)==typeid(*pbase) ) << endl << endl;

// polymorphic types:
Poly_Derived polyderived;
Poly_Base* ppolybase = &polyderived;
cout << "polyderived is: " << typeid(polyderived).name() << endl;
cout << " *ppolybase is: " << typeid(*ppolybase).name() << endl;
cout << boolalpha << "same type? ";
cout << ( typeid(polyderived)==typeid(*ppolybase) ) << endl << endl;
}
[/code]

输出:

[code="plain"]
int is: int
i is: int
pi is: int *
*pi is: int

derived is: struct Derived
*pbase is: struct Base
same type? false

polyderived is: struct Poly_Derived
*ppolybase is: struct Poly_Derived
same type? true
[/code]

Jun17

【转载】md5加密算法c++实现64位修复版

Author: leeon  Click: 10273   Comments: 0 Category: c/c++  Tag: md5,encrypt,c++,cpp,fix

     感谢作者蚂蚁终结者提供的c++版本md5实现,本人已经在多个项目中使用,速度非常快,封装的很棒。今日在做32位程序移植时发现作者提供的版本在linux64下算出的md5值全部错误,看到http://www.cppblog.com/ant/archive/2007/09/11/31886.html 作者文章下有一些童鞋反馈了解决64位移植问题的方法,两个评论的做法在我的centos5.8 环境测试不通过,作者原先是自定义了一个ulong别名,其实在linux的定义中可以用uint32_t来代替。索性将作者原有代码中的ulong全部替换成uint32_t,同时删除原先ulong的定义。 

此版本已经在32为和64位centos5.8系统下测试通过!

md5.h 代码:

[code="cpp"]
#ifndef MD5_H
#define MD5_H

#include <string>
#include <fstream>
#include<string.h>
#include<stdint.h>


/* Type define */
typedef unsigned char byte;

using std::string;
using std::ifstream;

/* MD5 declaration. */
class MD5 {
public:
MD5();
MD5(const void *input, size_t length);
MD5(const string &str);
MD5(ifstream &in);
void update(const void *input, size_t length);
void update(const string &str);
void update(ifstream &in);
const byte* digest();
string toString();
void reset();
private:
void update(const byte *input, size_t length);
void final();
void transform(const byte block[64]);
void encode(const uint32_t *input, byte *output, size_t length);
void decode(const byte *input, uint32_t *output, size_t length);
string bytesToHexString(const byte *input, size_t length);

/* class uncopyable */
MD5(const MD5&);
MD5& operator=(const MD5&);
private:
uint32_t _state[4]; /* state (ABCD) */
uint32_t _count[2]; /* number of bits, modulo 2^64 (low-order word first) */
byte _buffer[64]; /* input buffer */
byte _digest[16]; /* message digest */
bool _finished; /* calculate finished ? */

static const byte PADDING[64]; /* padding for calculate */
static const char HEX[16];
static const size_t BUFFER_SIZE = 1024;
};

#endif/*MD5_H*/
[/code]

md5.cpp 代码:

[code="cpp"]
#include "md5.h"

using namespace std;

/* Constants for MD5Transform routine. */
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21


/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))

/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))

/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + ac; \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + ac; \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + ac; \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + ac; \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}


const byte MD5::PADDING[64] = { 0x80 };
const char MD5::HEX[16] = {
'0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'a', 'b',
'c', 'd', 'e', 'f'
};

/* Default construct. */
MD5::MD5() {
reset();
}

/* Construct a MD5 object with a input buffer. */
MD5::MD5(const void *input, size_t length) {
reset();
update(input, length);
}

/* Construct a MD5 object with a string. */
MD5::MD5(const string &str) {
reset();
update(str);
}

/* Construct a MD5 object with a file. */
MD5::MD5(ifstream &in) {
reset();
update(in);
}

/* Return the message-digest */
const byte* MD5::digest() {
if (!_finished) {
_finished = true;
final();
}
return _digest;
}

/* Reset the calculate state */
void MD5::reset() {

_finished = false;
/* reset number of bits. */
_count[0] = _count[1] = 0;
/* Load magic initialization constants. */
_state[0] = 0x67452301;
_state[1] = 0xefcdab89;
_state[2] = 0x98badcfe;
_state[3] = 0x10325476;
}

/* Updating the context with a input buffer. */
void MD5::update(const void *input, size_t length) {
update((const byte*)input, length);
}

/* Updating the context with a string. */
void MD5::update(const string &str) {
update((const byte*)str.c_str(), str.length());
}

/* Updating the context with a file. */
void MD5::update(ifstream &in) {

if (!in)
return;

std::streamsize length;
char buffer[BUFFER_SIZE];
while (!in.eof()) {
in.read(buffer, BUFFER_SIZE);
length = in.gcount();
if (length > 0)
update(buffer, length);
}
in.close();
}

/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void MD5::update(const byte *input, size_t length) {

uint32_t i, index, partLen;

_finished = false;

/* Compute number of bytes mod 64 */
index = (uint32_t)((_count[0] >> 3) & 0x3f);

/* update number of bits */
if((_count[0] += ((uint32_t)length << 3)) < ((uint32_t)length << 3))
_count[1]++;
_count[1] += ((uint32_t)length >> 29);

partLen = 64 - index;

/* transform as many times as possible. */
if(length >= partLen) {

memcpy(&_buffer[index], input, partLen);
transform(_buffer);

for (i = partLen; i + 63 < length; i += 64)
transform(&input[i]);
index = 0;

} else {
i = 0;
}

/* Buffer remaining input */
memcpy(&_buffer[index], &input[i], length-i);
}

/* MD5 finalization. Ends an MD5 message-_digest operation, writing the
the message _digest and zeroizing the context.
*/
void MD5::final() {

byte bits[8];
uint32_t oldState[4];
uint32_t oldCount[2];
uint32_t index, padLen;

/* Save current state and count. */
memcpy(oldState, _state, 16);
memcpy(oldCount, _count, 8);

/* Save number of bits */
encode(_count, bits, 8);

/* Pad out to 56 mod 64. */
index = (uint32_t)((_count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
update(PADDING, padLen);

/* Append length (before padding) */
update(bits, 8);

/* Store state in digest */
encode(_state, _digest, 16);

/* Restore current state and count. */
memcpy(_state, oldState, 16);
memcpy(_count, oldCount, 8);
}

/* MD5 basic transformation. Transforms _state based on block. */
void MD5::transform(const byte block[64]) {

uint32_t a = _state[0], b = _state[1], c = _state[2], d = _state[3], x[16];

decode(block, x, 64);

/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */

/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */

/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */

/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */

_state[0] += a;
_state[1] += b;
_state[2] += c;
_state[3] += d;
}

/* Encodes input (uint32_t) into output (byte). Assumes length is
a multiple of 4.
*/
void MD5::encode(const uint32_t *input, byte *output, size_t length) {

for(size_t i=0, j=0; j<length; i++, j+=4) {
output[j]= (byte)(input[i] & 0xff);
output[j+1] = (byte)((input[i] >> 8) & 0xff);
output[j+2] = (byte)((input[i] >> 16) & 0xff);
output[j+3] = (byte)((input[i] >> 24) & 0xff);
}
}

/* Decodes input (byte) into output (uint32_t). Assumes length is
a multiple of 4.
*/
void MD5::decode(const byte *input, uint32_t *output, size_t length) {

for(size_t i=0, j=0; j<length; i++, j+=4) {
output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) |
(((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
}
}

/* Convert byte array to hex string. */
string MD5::bytesToHexString(const byte *input, size_t length) {
string str;
str.reserve(length << 1);
for(size_t i = 0; i < length; i++) {
int t = input[i];
int a = t / 16;
int b = t % 16;
str.append(1, HEX[a]);
str.append(1, HEX[b]);
}
return str;
}

/* Convert digest to string value */
string MD5::toString() {
return bytesToHexString(digest(), 16);
}
[/code]

Mar11

【原创】关于C中静态和非静态全局变量的区别小记

Author: leeon  Click: 6054   Comments: 0 Category: c/c++  Tag: c,static,全局变量

今天在看华为C语言面试题的时候重温了一下全局变量的一些知识,这里记录一下静态和非静态全局变量中最大的一个区别。

摘录一个网上关于其只是的区别说明:

全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。

这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。

 

好了我们开始来实践:

编写一个a.h头文件:

[code="cpp"]
#ifndef A_H
#define A_H

#ifdef __cplusplus
extern "C" {
#endif
int statica;
void func();
#ifdef __cplusplus
}
#endif

#endif /* A_H */
[/code]

注意头文件中我们没有申明statica变量为static,然后编写一个main.c和test.c文件

main.c

[code="cpp"]

#include
#include
#include"a.h"
using namespace std;



int main(int argc, char** argv) {

statica = 3;
func();
printf("%d",statica);
}
[/code]

test.c

[code="cpp"]
#include"a.h"

void func(){
statica = 4;
}
[/code]

运行后可以看出printf得出的是4,那么说明func函数跨文件修改了main.c中非静态全局变量的值,

然后加上static对statica变量的申明再次运行,可以得出输出的指为3,说明test.c的func没有对main.c中的statica变量产生干扰,这样可以利用static申明有效屏蔽多文件中共享同一个头文件时有可能导致的全局变量被不断覆写的问题。

Jan24

【原创】sshpass在ssh2有可能无法自动输入密码问题解决

Author: leeon  Click: 7706   Comments: 0 Category: c/c++  Tag: sshpass

公司的ssh2整合了ldap,当ssh登录时密码提示并不能在当前最新版本的sshpass上被捕获,导致无法实现自动输入密码,现在sshpass1.05的版本基础上增加两行代码即可

修改main.c文件:

[code="cpp"]
setsid();
// This line makes the ptty our controlling tty. We do not otherwise need it open
slavept=open(name, O_RDWR );

dup2(slavept,STDERR_FILENO);// 增加错误输出文件描述符重定向到伪终端
close( slavept );

close( masterpt );

char **new_argv=malloc(sizeof(char *)*(argc+1));

[/code]

 [code="cpp"]
terminate=ret;
if( terminate ) {
close( slavept );
}
kill(childpid, SIGKILL ); //增加当handleoutput返回的数值大于0,也就是异常的时候直接杀死子进程,避免当在ldap验证的时候密码提示重复输入导致异常
[/code]

改造后在使用ssh的时候最好带上"-o StrictHostKeyChecking=no' 因为原先的sshpass对这种情况是没有做验证的,在ssh2下这里弹出的提示并不是错误输出,验证了多次我始终不能解决让程序自行判断提示自动输入yes。

分类

标签

归档

最新评论

Abyss在00:04:28评论了
Linux中ramdisk,tmpfs,ramfs的介绍与性能测试
shallwe99在10:21:17评论了
【原创】如何在微信小程序开发中正确的使用vant ui组件
默一在09:04:53评论了
Berkeley DB 由浅入深【转自架构师杨建】
Memory在14:09:22评论了
【原创】最佳PHP框架选择(phalcon,yaf,laravel,thinkphp,yii)
leo在17:57:04评论了
shell中使用while循环ssh的注意事项

我看过的书

链接

其他

访问本站种子 本站平均热度:8823 c° 本站链接数:1 个 本站标签数:464 个 本站被评论次数:94 次