/* Copyright (C) 2020 Gentoo-libre Install This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include //store if number is negative //powq(): square roots unsigned long powq(int number, int power) { unsigned long result = 1;//result int, 1 by default if (!power){return 1;}//if to the power of 0, return 1 while(power)//loop until all powers have been calculated { result *= number;//in the end result=number*number*number*etc until power is reached --power;//--power since a power has been calculated } return result; } //itoh(): Convert a string of decimal numbers to a string of hex. (No negative input num handling, no invalid char handling and ignores overflows) void itoh(char s[], char *result) { int i; //counter variable for(i=0;i<16;++i){result[i]='0';}//zero out the result string (16 chars due to that being the size of unsigned long long int max) int power = 0; //int to store the power. while(s[power] != '\0'){++power;}//increment power for however many non-null chars in the string. --power;//The correct power is actually one less than above returns unsigned long long integer = 0; //the variable in which the integer result from the input string is stored. i=0;//reset the counter int while (s[i] != '\0')//convert the string of decimal numbers into a long long int { if (s[i] >= '0' && s[i] <= '9'){integer += ((s[i] - '0') * powq(10,power));}//integer = integer + ([char converted to number] * (10^[position of number in string])) ++i; --power;//Deincrement the power. E.g. ([charvalue]*(10^3))+([nextcharvalue]*(10^2)) etc } //convert the long long into a string of ASCII hex i=15;//Write string right to left int temp; while(integer) { temp = (integer % 16);//temp = value to encode into ASCII char if ((temp>=0)&&(temp<=9)){result[i] = temp + '0'; goto skip;}//if temp is 0-9, convert that to a digit and skip checking for A-F if ((temp>=10)&&(temp<=15)){result[i] = temp + 55;}//if temp is 10-15, convert that to A-F skip: integer/=16;//divide integer by 16 to allow generating the next ASCII char --i;//write to the next digit to the left } } int main(int argc, char *argv[]) { bool negative = false; //handle negative numbers if (!argv[1]){goto stdinMode;} if (argv[1][1] == '-') { printf("Usage (stdin mode): %s\n", argv[0]); printf("Ctrl+D to exit\n"); printf("Usage (cli args mode): %s [decnum]\n", argv[0]); printf("Licence: AGPLv3\n"); return 0; } //result hex string, passed to itoh(); char *cli = malloc(17*sizeof(char)); if (!cli){printf("Malloc failed!\n"); return 1;} cli[16]='\0';//add null terminating char //strip out invalid chars from the input string if (argv[1][0] == '-'){negative = true;}//handle negative numbers int a,q;//counter variables for (a=0; argv[1][a] != '\0'; ++a) { if ((argv[1][a] < '0')||(argv[1][a] > '9'))//if argv[1][i] is a character to remove.... { q=a; while(argv[1][q] != '\0'){argv[1][q++] = argv[1][q+1];}//shift all characters above left, overwriting the character --a;//deincrement a, since the string was just shrunk by one and the one just above could indeed be a matching char } } itoh(argv[1], cli); if (negative){printf("-%s\n",cli); free(cli); return 0;}//handle negative numbers printf("%s\n",cli);//print string with all leading 0's free(cli); return 0; stdinMode: ; //input decimal string, by default 10 chars long int size = 10; char *input = malloc(size*sizeof(char)); if (!input){printf("Malloc failed!\n"); return 1;} //result hex string char *result = malloc(17*sizeof(char)); if (!result){printf("Malloc failed!\n"); return 1;} result[16]='\0';//add null terminating char int i; nextnum: i=0; char c; while ((c=getchar())!='\n') { if (c==EOF){free(result); free(input); exit(0);}//exit if EOF if (i>size-2){size+=4; input=realloc(input,size*sizeof(char)); if (!input){printf("Realloc failed!\n"); return 1;}}//relloc if the input string is longer than size input[i]=c;//write c to the string ++i; } input[i] = '\0'; //add NULL char for itoh //strip out invalid chars from the input string if (input[0] == '-'){negative = true;}//handle negative numbers int j;//another counter variable for (i=0; input[i] != '\0'; ++i) { if ((input[i] < '0')||(input[i] > '9'))//if input[i] is an invalid character { j=i; while(input[j] != '\0'){input[j++] = input[j+1];}//shift all characters above left, overwriting the character --i;//deincrement i, since the string was just shrunk by one and the one just above could indeed be a matching char } } itoh(input, result);//itoh(): Given input string and a pointer to the result string i=0; while(result[i] == '0'){++i;}//increment i until a non-0 char is found if (i == 16){--i;}//if all characters are 0, leave a 0 so the string isn't null int x;//another counter variable if (i){for(x=0;result[i-1]!='\0';++x){result[x]=result[i];++i;}}//copy non-0 characters to the left so there aren't any 0's in front of the output number. (Also don't do this if i=0 (there are no 0's)) if (negative){printf("Hexadecimal: -0x%s\n",result); negative = false; goto nextnum;}//handle negative numbers printf("Hexadecimal: 0x%s\n",result); goto nextnum; //process another number //these won't be reached, but included anyway in case the above goto is removed free(input); free(result); return 0; }