Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting a hexadecimal number into a program via the command line

I can do this:

int main(int argc, char** argv) {
  unsigned char cTest = 0xff;
  return 0;
}

But what's the right way to get a hexadecimal number into the program via the command line?

unsigned char cTest = argv[1];

doesn't do the trick. That produces a initialization makes integer from pointer without a cast warning.

like image 983
Pieter Avatar asked Jan 29 '10 15:01

Pieter


People also ask

How do you input hexadecimal?

In C programming language, hexadecimal value is represented as 0x or 0X and to input hexadecimal value using scanf which has format specifiers like %x or %X.

How do you pass a hexadecimal value in Python?

Python hex() function is used to convert an integer to a lowercase hexadecimal string prefixed with “0x”. We can also pass an object to hex() function, in that case the object must have __index__() function defined that returns integer. The input integer argument can be in any base such as binary, octal etc.

How do you write hex in C++?

Hexadecimal uses the numeric digits 0 through 9 and the letters 'a' through 'f' to represent the numeric values 10 through 15). Each hex digit is directly equivalent to 4 bits. C++ precedes a hexadecimal value that it prints with the characters "0x" to make it clear that the value is in base 16.

What is a hex command?

The HEX command is used to obtain the hexadecimal equivalent of a decimal number. HEX + - decval. +decval -decval. For decval, specify the 1- to 8-digit decimal number that is to be converted to hexadecimal notation. The hexadecimal number is returned as a fullword.


2 Answers

I think some people arriving here might just be looking for:

$ ./prog `python -c 'print "\x41\x42\x43"'`
$ ./prog `perl -e 'print "\x41\x42\x43"'`
$ ./prog `ruby -e 'print "\x41\x42\x43"'`
like image 195
Peter Le Bek Avatar answered Sep 30 '22 09:09

Peter Le Bek


As the type of main indicates, arguments from the command line are strings and will require conversion to different representations.

Converting a single hexadecimal command-line argument to decimal looks like

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  printf("%ld\n", strtol(argv[1], NULL, 16));

  return 0;
}

Example usage:

$ ./hex ff
255

Using strtol and changing the final argument from 16 to 0 as in

printf("%ld\n", strtol(argv[1], NULL, 0));

makes the program accept decimal, hexadecimal (indicated by leading 0x, and octal (indicated by leading 0) values:

$ ./num 0x70
112
$ ./num 070
56
$ ./num 70
70

Using the bash command shell, take advantage of ANSI-C Quoting to have the shell perform the conversion, and then your program just prints the values from the command line.

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
  int i;
  for (i = 1; i < argc; i++) {
    unsigned char value = argv[i][0];
    if (strlen(argv[i]) > 1)
      fprintf(stderr, "%s: '%s' is longer than one byte\n", argv[0], argv[i]);

    printf(i + 1 < argc ? "%u " : "%u\n", value);
  }

  return 0;
}

Bash supports many formats of the form $'...', but $'\xHH' appears to be the closest match to your question. For example:

$ ./print-byte $'\xFF' $'\x20' $'\x32'
255 32 50

Maybe you pack the values from the command line into a string and print it.

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
  int i;

  if (argc > 1) {
    char *s = malloc(argc);
    if (!s) {
      fprintf(stderr, "%s: malloc: %s\n", argv[0], strerror(errno));
      return 1;
    }

    for (i = 1; i < argc; i++)
      s[i - 1] = strtol(argv[i], NULL, 16) & 0xff;

    s[argc - 1] = '\0';
    printf("%s\n", s);
    free(s);
  }

  return 0;
}

In action:

$ ./pack-string 48 65 6c 6c 6f 21
Hello!

All of the above is reinventing wheels that bash and the operating system already provide for you.

$ echo $'\x48\x65\x6c\x6c\x6f\x21'
Hello!

The echo program prints its command-line arguments on the standard output, which you can think of as a for loop over the arguments and a printf for each.

If you have another program that performs the decoding for you, use Command Substitution that replaces a command surrounded by backticks or $() with its output. See examples below, which again use echo as a placeholder.

$ echo $(perl -e 'print "\x50\x65\x72\x6c"')
Perl
$ echo `python -c 'print "\x50\x79\x74\x68\x6f\x6e"'`
Python
like image 40
Greg Bacon Avatar answered Sep 30 '22 11:09

Greg Bacon