C++ 常见进制转换代码
目录
C++ 进制转换代码记录
一丶进制转换
1.1 介绍
再平常写代码的时候经常会用到进制转换。 比如16进制转为10进制。
16进制值转为Ascii等。所以这里启用一个整理。方便下次炒代码。
代码来源于网上以及朋友提供的。
二丶 十六进制字符串转换为Ascii
2.1 方法1 Char类型操作
//************************************
// Parameter: 要进行转换的十六进制字符串
// Parameter: 十六进程字符串的长度
// Parameter: 传出的缓冲区,结果存放在此缓冲区,请注意一定保证缓冲区大小
//************************************
void CFileOpt::Hex2Asc1(IN unsigned char *hex, IN int hexlength, OUT unsigned char *asc)
{
for (int i = 0; i < hexlength; i++)
{
sprintf((char*)asc + 2 * i, "%02X", hex[i]);
}
}
2.2 方法2 STL String操作
//************************************
// Parameter: 要进行转换的十六进制字符串 string类型
// Return: 返回转换后的结构字符串
//************************************
std::string HexToAsc(string hexStr)
{
string res = "";
unsigned char* hexDigitTable = (unsigned char*)"0123456789abcdef";
for (int i = 0; i < hexStr.length(); i++)
{
unsigned char asciiDigit1 = hexDigitTable[hexStr.at(i) & 0x0f];
unsigned char asciiDigit0 = hexDigitTable[(hexStr.at(i) & 0xf0) >> 4];
res += asciiDigit0;
res += asciiDigit1;
}
return res;
}
2.3 方法3 google写法
这种方式是从逆向google Chrome的时候得到的。自己封装的
当然你可以自己修改参数
//************************************
// Parameter: 要进行转换的十六进制字符串
// Parameter: 十六进制字符串的长度
// Parameter: 传出的string 是一个指针 外面可以传递 &strxxx 也可以修改为引用
//************************************
bool Hex2Asc2(
const unsigned char* data,
int data_len,
std::string* string) {
if (!string)
return false;
string->clear();
if (data_len < 1 || !data)
return false;
static const char kHex[] = "0123456789ABCDEF";
// Fix the buffer size to begin with to avoid repeated re-allocation.
string->resize(data_len * 2);
int index = data_len;
while (index--) {
string->at(2 * index) = kHex[data[index] >> 4]; // high digit
string->at(2 * index + 1) = kHex[data[index] & 0x0F]; // low digit
}
return true;
}
2.4 总结
上述方法命令结果为如下
IN -> "AABB"
OUT-> "41414242"
三丶Ascii字符串转为16进制字符串
3.1 方法1 字符指针类型转换
//************************************
// Parameter: 带转换的的Ascii编码
// Parameter: 长度
// Parameter: 传出结果,是一个16进制字符串。
//************************************
void asc2hex(
IN unsigned char *asc,
IN int hexlength,
OUT unsigned char *hex)
{
if (strlen((char*)asc) < hexlength * 2)
{
char *asc_temp = new char[hexlength * 2 + 1];
memset(asc_temp, 'F', hexlength * 2 + 1);
memcpy(asc_temp, asc, strlen((char*)asc));
for (int i = 0; i < hexlength; i++)
{
char temp[3] = { asc_temp[i * 2], asc_temp[i * 2 + 1] };
hex[i] = strtol(temp, 0, 16);
}
delete[]asc_temp;
}
else
{
for (int i = 0; i < hexlength; i++)
{
char temp[3] = { asc[i * 2], asc[i * 2 + 1] };
hex[i] = strtol(temp, 0, 16);
}
}
}
四丶十六进制字符转为整数
4.1 方法1 字符转为整数
int Hex2Int(char c) {
return (c >= '0' && c <= '9') ? (c)-'0' :
(c >= 'A' && c <= 'F') ? (c)-'A' + 10 :
(c >= 'a' && c <= 'f') ? (c)-'a' + 10 : 0;
}
IN -> 'F'
OUT -> 15
五丶十六进制字符串转为二进制
5.1 十六进制字符串转为二进制类型
//************************************
// Parameter: 要转换的16进制字符串
// Parameter: 要转换的16进制字符串大小
// Parameter: 转换后的传出数据
// 传入16进制字符串 "AABB" 则 传出数据的Buff里面的字节则是 buf[0] = 'AA' buf[1] = '\xBB' 字节
//************************************
void Hex2Bin(const unsigned char* hex, int sz, unsigned char* out) {
int i;
for (i = 0; i < sz; i += 2) {
out[i / 2] = (Hex2Int(hex[i]) << 4) | Hex2Int(hex[i + 1]);
}
}
5.2 二进制类型十六进制转为十六进制字符串
//************************************
// Parameter: 代转换的Buff 设Buf[0] = 0xAA buf[1] = 0xBB
// Parameter: buf大小
// Parameter: 传出结果,是一个16进制字符串。
//传出的是"AABB"
//************************************
void Bin2Hex(const unsigned char* in, int sz, char* out) {
int i;
for (i = 0; i < sz; i++) {
sprintf_s(out + (i * 2), 4, "%02x", in[i]);
}
}
六丶10进制数字转为16进制字符串
公共头文件
#include <iostream>
#include <sstream>
#include <cstdio>
#include <algorithm>
6.1方法1 STL版
//************************************
// Parameter: 要转换的10进制数
// Parameter: 转换后的结果是否添加前缀 0x
// Parameter: 转换后的结果是否是大写
// 默认值返回大写不带前缀的十六进制字符串
//************************************
string dec2hex1(
IN unsigned long long i,
IN bool isAddPrefix = false,
IN bool isUpcase = true)
{
stringstream ss;
if (isAddPrefix)
{
if (isUpcase)
{
ss << showbase << hex << uppercase << i; //prepends 0x
}
else
{
ss << showbase << hex << nouppercase << i; //prepends 0x
}
}
else
{
if (isUpcase)
{
ss << hex << uppercase << i;
}
else
{
ss << hex << nouppercase << i;
}
}
return ss.str();
}
//************************************
// Parameter: 要转换的10进制数
// Parameter: 转换后的结果是否添加前缀 0x
// Parameter: 转换后的结果是否是大写
// 默认值返回大写不带前缀的十六进制字符串
//************************************
string dec2hex2(
IN unsigned long long i,
IN bool isAddPrefix = false,
IN bool isUpcase = true)
{
stringstream ss;
string s;
if (isAddPrefix)
{
if (isUpcase)
{
ss << showbase << hex << uppercase << i; //prepends 0x
}
else
{
ss << showbase << hex << nouppercase << i; //prepends 0x
}
}
else
{
if (isUpcase)
{
ss << hex << uppercase << i;
}
else
{
ss << hex << nouppercase << i;
}
}
ss >> s;
return s;
}
6.2 方法2 C库函数版
//************************************
// Parameter: 要转换的10进制数
// Parameter: 转换后的结果是否添加前缀 0x
// Parameter: 转换后的结果是否是大写
// 默认值返回大写不带前缀的十六进制字符串
//************************************
string CFileOpt::dec2hex_c(
IN unsigned long long i,
IN bool isAddPrefix,
IN bool isUpcase)
{
if (isAddPrefix)
{
if (isUpcase)
{
char s[20];
sprintf(s, "0X%X", i);
return string(s);
}
else
{
char s[20];
sprintf(s, "0x%x", i);
return string(s);
}
}
else
{
if (isUpcase)
{
char s[20];
sprintf(s, "%X", i);
return string(s);
}
else
{
char s[20];
sprintf(s, "%x", i);
return string(s);
}
}
return "";
}
七丶 String和Wstring的互相转换
7,1 WinApi方式
头文件
#include <windows.h>
std::wstring String2Wstring(std::string str)
{
wstring result = L"";
int len = 0;
wchar_t* buffer = nullptr;
do
{
len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), NULL, 0);
if (len <= 0) break;
buffer = new wchar_t[len + 1]();
if (buffer == nullptr)break;
len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), buffer, len);
if (len <= 0)break;
buffer[len] = L'\0';
result.append(buffer);
} while (false);
if (buffer != nullptr)
{
delete[] buffer;
buffer = nullptr;
}
return result;
}
std::string Wstring2String(std::wstring str) {
string result = "";
int len = 0;
char* buffer = nullptr;
do
{
len = WideCharToMultiByte(CP_ACP, 0, str.c_str(), str.size(), NULL, 0, NULL, NULL);
if (len <= 0) break;
buffer = new char[len + 1]();
if (buffer == nullptr) break;
len = WideCharToMultiByte(CP_ACP, 0, str.c_str(), str.size(), buffer, len, NULL, NULL);
if (len <= 0) break;
buffer[len] = '\0';
result.append(buffer);
} while (false);
if (buffer != nullptr)
{
delete[] buffer;
buffer = nullptr;
}
return result;
}
7.2 BSTR过渡版
#include <comutil.h>
#pragma comment(lib, "comsuppw.lib")
string wstring2string(const wstring& ws)
{
_bstr_t t = ws.c_str();
char* pchar = (char*)t;
string result = pchar;
return result;
}
wstring string2wstring(const string& s)
{
_bstr_t t = s.c_str();
wchar_t* pwchar = (wchar_t*)t;
wstring result = pwchar;
return result;
}
7.3 CRT库版本,平台无关。
#include <string>
#include <locale.h>
using namespace std;
string ws2s(const wstring& ws)
{
string curLocale = setlocale(LC_ALL, NULL); // curLocale = "C";
setlocale(LC_ALL, "chs");
const wchar_t* _Source = ws.c_str();
size_t _Dsize = 2 * ws.size() + 1;
char *_Dest = new char[_Dsize];
memset(_Dest,0,_Dsize);
wcstombs(_Dest,_Source,_Dsize);
string result = _Dest;
delete []_Dest;
setlocale(LC_ALL, curLocale.c_str());
return result;
}
wstring s2ws(const string& s)
{
setlocale(LC_ALL, "chs");
const char* _Source = s.c_str();
size_t _Dsize = s.size() + 1;
wchar_t *_Dest = new wchar_t[_Dsize];
wmemset(_Dest, 0, _Dsize);
mbstowcs(_Dest,_Source,_Dsize);
wstring result = _Dest;
delete []_Dest;
setlocale(LC_ALL, "C");
return result;
}
7.4 U8宽字符类型的转换
头文件应该是以下几个,具体哪个我忘了索性都写出来。可以尝试删除
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <codecvt>
std::string to_byte_string(const std::wstring & input)
{
//std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
return converter.to_bytes(input);
}
std::wstring to_wide_string(const std::string & input)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
return converter.from_bytes(input);
}
7.5 API版Asc转换为U8
std::string AnisToUTF8(const std::string& Str)
{
int nwLen = ::MultiByteToWideChar(CP_ACP, 0, Str.c_str(), -1, NULL, 0);
wchar_t* pwBuf = new wchar_t[(size_t)nwLen + 1];
ZeroMemory(pwBuf, (size_t)nwLen * 2 + 2);
::MultiByteToWideChar(CP_ACP, 0, Str.c_str(), Str.length(), pwBuf, nwLen);
int nLen = ::WideCharToMultiByte(CP_UTF8, 0, pwBuf, -1, NULL, NULL, NULL, NULL);
char* pBuf = new char[(size_t)nLen + 1];
ZeroMemory(pBuf, (size_t)nLen + 1);
::WideCharToMultiByte(CP_UTF8, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);
std::string retStr(pBuf);
delete[]pwBuf;
delete[]pBuf;
pwBuf = NULL;
pBuf = NULL;
return retStr;
}
作者:IBinary
坚持两字,简单,轻便,但是真正的执行起来确实需要很长很长时间.当你把坚持两字当做你要走的路,那么你总会成功. 想学习,有问题请加群.群号:725864912(收费)群名称: 逆向学习小分队 群里有大量学习资源. 以及定期直播答疑.有一个良好的学习氛围. 涉及到外挂反外挂病毒 司法取证加解密 驱动过保护 VT 等技术,期待你的进入。
详情请点击链接查看置顶博客 https://www.cnblogs.com/iBinary/p/7572603.html
本文来自博客园,作者:iBinary,未经允许禁止转载 转载前可联系本人.对于爬虫人员来说如果发现保留起诉权力.https://www.cnblogs.com/iBinary/p/16262184.html
欢迎大家关注我的微信公众号.不定期的更新文章.更新技术. 关注公众号后请大家养成 不白嫖的习惯.欢迎大家赞赏. 也希望在看完公众号文章之后 不忘 点击 收藏 转发 以及点击在看功能.![微信公众号](https://images.cnblogs.com/cnblogs_com/iBinary/1827080/o_220306121308_qrcode_for_gh_b8b8f84e4988_258.jpg)
![QQ群](https://images.cnblogs.com/cnblogs_com/iBinary/1827080/o_21062107294320210621152919.png)