将二进制数据转换为可打印的十六进制 [英] Converting binary data to printable hex

查看:171
本文介绍了将二进制数据转换为可打印的十六进制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

线程中,有人评论说,以下代码只应在玩具项目。不幸的是,他没有回来说为什么它不是生产质量,所以我希望在社区中的一个人可能能够保证我的代码是确定(因为我很喜欢它)或识别什么是错误。 p>

In this thread some one commented that the following code should only be used in 'toy' projects. Unfortunately he hasn't come back to say why it's not of production quality so I was hoping some one in the community may be able to either assure me the code is ok (because I quite like it) or identify what is wrong.

template< class T1, class T2>
void hexascii( T1& out, const T2& in )
{
    out.resize( in.size() * 2 );
    const char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7','8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    T1::iterator outit = out.begin();
    for( T2::const_iterator it = in.begin(); it != in.end(); ++it )
    {
        *outit++ = hexDigits[*it >> 4];
        *outit++ = hexDigits[*it & 0xF];
    }
}

template<class T1, class T2>
void asciihex( T1& out, const T2& in )
{
    size_t size = in.size;
    assert( !(size % 2) );

    out.resize( size / 2 );
    T1::iterator outit = out.begin();
    for( T2::const_iterator it = in.begin(); it != in.end(); it += 2, ++outit )
    {
    *outit = ((( (*it > '9' ? *it - 0x07 : *it)  - 0x30) << 4) & 0x00f0) + 
                (((*(it+1) > '9' ? *(it+1) - 0x07 : *(it+1)) - 0x30) & 0x000f);
    }
}

编辑:感谢您的帮助,做了一些大的改进。我从你的答案中写了两个建议的风格的函数。一些粗略的测试表明,第二种方法比第一种方法快一些,但是IMO比第一种方法的可读性更好。

Thanks for your help guys, you've made some big improvements. I've written functions in the two suggested styles from your answers. Some rough testing suggests the second method is marginally faster than the first, but IMO this is outweighed by the improved readability of the first.

template<class T1>
void asciihex2( T1& out, const std::string& in )
{
    dassert( sizeof(T1::value_type)==1 );
    size_t size = in.size();
assert( !(size % 2) );
    out.resize( size / 2 );
    T1::iterator outit = out.begin();
    for( size_t i = 0; i < in.size(); i += 2 )
    {
        int tmp;
        sscanf( in.c_str() + i, "%02X", &tmp );
        *outit++ = tmp;
    }
}

template<class T1>
void asciihex3( T1& out, const std::string& in )
{
    dassert( sizeof(T1::value_type)==1 );
    size_t size = in.size();
assert( !(size % 2) );
    out.resize( size / 2 );
    T1::iterator outit = out.begin();
const char hexDigits[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 
	                      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			      0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
for( std::string::const_iterator it = in.begin(); it != in.end(); it += 2, ++outit )
    {
    *outit = (hexDigits[(*it - 0x30) & 0x1f] << 4) + 
		      hexDigits[((*(it+1) - 0x30) & 0x1f)];
    }
}

这些代码的一些假设:
1:它们不是作为一个泛型,而是在匿名命名空间中用于翻译特定类的数据。
2:模板是必需的,因为正在使用两个独立的容器类型(一个是std :: vector,另一个是来自第三方库的类似的字节数组类型容器)
3:目的是能够将不确定长度的二进制数据转换为字符串并再次返回(0x1234abcd <1234>1234abcd)
4:在调试和释放模式中都断言陷阱错误
5:到这些函数被调用的字符串的大小已经被检查,assert用于终止处理如果发生严重错误
6:需要一些注释

Some of the assumptions surronding this code: 1: They are not intended as a generic, but are used in an anonymous name space to translate data for a specific class. 2: The templating is required as two separate container types are being used (one being std::vector, the other a similar byte array type container from a third party library. 3: The purpose is to be able to convert binary data of indeterminate length into strings and back again (0x1234abcd <-> "1234abcd") 4: assert traps errors in both debug and release modes 5: by the time these functions are called the size of the string will already have been checked, assert is used to terminate processing if something serious has gone wrong 6: It needs some commenting

任何其他想法赞赏。

推荐答案

似乎很多模板代码实现非常少,标准C scanf printf 功能,为什么要这么做?

It seems like a lot of templated code to achieve very little, given you have direct hex conversion in the standard C scanf and printf functions. why bother?

这篇关于将二进制数据转换为可打印的十六进制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆