dígitos hexadecimales son muy fáciles de convertir a binario:
// C++98 guarantees that '0', '1', ... '9' are consecutive.
// It only guarantees that 'a' ... 'f' and 'A' ... 'F' are
// in increasing order, but the only two alternative encodings
// of the basic source character set that are still used by
// anyone today (ASCII and EBCDIC) make them consecutive.
unsigned char hexval(unsigned char c)
{
if ('0' <= c && c <= '9')
return c - '0';
else if ('a' <= c && c <= 'f')
return c - 'a' + 10;
else if ('A' <= c && c <= 'F')
return c - 'A' + 10;
else abort();
}
Así que para hacer toda la cadena se ve algo como esto:
void hex2ascii(const string& in, string& out)
{
out.clear();
out.reserve(in.length()/2);
for (string::const_iterator p = in.begin(); p != in.end(); p++)
{
unsigned char c = hexval(*p);
p++;
if (p == in.end()) break; // incomplete last digit - should report error
c = (c << 4) + hexval(*p); // + takes precedence over <<
out.push_back(c);
}
}
Usted puede preguntar razonablemente por qué se podría hacer de esta manera cuando hay strtol
, y su uso es significativamente menos código (como en la respuesta de James Curran). Bueno, ese enfoque es un orden decimal completo de magnitud más lento, porque copia cada fragmento de dos bytes (posiblemente asignando memoria de pila para hacerlo) y luego invoca una rutina general de conversión de texto a número que no se puede escribir de manera eficiente como el código especializado de arriba. El enfoque de Christian (usando istringstream) es cinco veces más lento que que. Aquí hay una trama de referencia: puedes notar la diferencia incluso con un pequeño bloque de datos para decodificar, y se hace evidente a medida que las diferencias se agrandan. (Tenga en cuenta que ambos ejes están en una escala logarítmica.)

¿Es esta optimización prematura? Diablos no Este es el tipo de operación que se empuja en una rutina de biblioteca, olvidada y luego llamada miles de veces por segundo. Necesita gritar. Trabajé en un proyecto hace unos años que hizo un uso intensivo de las sumas de comprobación SHA1 internamente: obtuvimos entre 10 y 20% de aceleraciones en operaciones comunes al almacenarlas como bytes sin procesar en lugar de hexadecimales, convirtiendo solo cuando teníamos que mostrarlas a la usuario, y eso fue con las funciones de conversión que ya se habían ajustado a la muerte. Uno podría honestamente preferir la brevedad al rendimiento aquí, dependiendo de cuál es la tarea más grande, pero si es así, ¿por qué diablos estás codificando en C++?
Además, desde una perspectiva pedagógica, creo que es útil mostrar ejemplos codificados a mano para este tipo de problema; revela más sobre lo que la computadora tiene que hacer.
asociado, véase [Conversión de cadena hexadecimal con "0x" inicial a corto firmado en C++?] (Http://stackoverflow.com/q/1487440/608639) – jww