char *addBinary(char *a, char *b) { int alen = strlen(a); int blen = strlen(b); int rlen = (alen > blen ? alen : blen) + 1; char *r = malloc(sizeof(char) * rlen + 1); r[rlen] = '\0'; int i, j, k, s, carry; for (i = alen - 1, j = blen - 1, k = rlen - 1, carry = 0; i >= 0 || j >= 0; i--, j--, k--) { s = (i >= 0) * char2digit(a[i]) + (j >= 0) * char2digit(b[j]) + carry; r[k] = digit2char(s % 2); carry = s / 2; } r[0] = digit2char(carry); // remove extra leading zero, but keep it if only one zero for (i = 0; i != rlen; i++) { if (r[i] != '0') { break; } } if (i != 0) { if (i == rlen) { i = rlen - 1; } for (j = i; j != rlen + 1; j++) { r[j - i] = r[j]; } } return r; }
static void isup_put_number(unsigned char *dest, char *src, int *len, int *oddeven) { int i = 0; int numlen = strlen(src); if (numlen % 2) { *oddeven = 1; *len = numlen/2 + 1; } else { *oddeven = 0; *len = numlen/2; } while (i < numlen) { if (!(i % 2)) dest[i/2] = char2digit(src[i]) & 0xf; else { dest[i/2] |= (char2digit(src[i]) << 4) & 0xf0; } i++; } }
/************************************************* * Decode a BigInt * *************************************************/ BigInt BigInt::decode(const byte buf[], u32bit length, Base base) { BigInt r; if(base == Binary) r.binary_decode(buf, length); #ifndef BOTAN_MINIMAL_BIGINT else if(base == Hexadecimal) { SecureVector<byte> hex; for(u32bit j = 0; j != length; j++) if(Hex_Decoder::is_valid(buf[j])) hex.append(buf[j]); u32bit offset = (hex.size() % 2); SecureVector<byte> binary(hex.size() / 2 + offset); if(offset) { byte temp[2] = { '0', hex[0] }; binary[0] = Hex_Decoder::decode(temp); } for(u32bit j = offset; j != binary.size(); j++) binary[j] = Hex_Decoder::decode(hex+2*j-offset); r.binary_decode(binary, binary.size()); } #endif else if(base == Decimal || base == Octal) { const u32bit RADIX = ((base == Decimal) ? 10 : 8); for(u32bit j = 0; j != length; j++) { byte x = char2digit(buf[j]); if(x >= RADIX) { if(RADIX == 10) throw Invalid_Argument("BigInt: Invalid decimal string"); else throw Invalid_Argument("BigInt: Invalid octal string"); } r = RADIX * r + x; } } else throw Invalid_Argument("Unknown BigInt decoding method"); return r; }
void printTelephoneWords(int start=0) { if(start == numLetters) { if(!firstWord) { printf(","); } for(int i=0;i<numLetters;++i) { printf("%c", str[i]); } firstWord = false; return; } int d = char2digit(digits[start]); char* letters = words[d]; while(*letters != '\0') { str[start] = *letters; printTelephoneWords(start+1); ++letters; } }
/* * Tries to parse a word as a number. * At the moment it only handles integers. * * if word is a valid integer, return a numeric value * if word is not a valid number, return a null value * * integer format: * [+-]?(0[XxBbDdOo])?[\d]+ * radices: * x = hex (digits 0-9, A-F, a-f) * b = binary (valid 0, 1) * d = decimal (valid 0-9) * o = octal (valid 0-7) */ value_t number(const char *word) { long acc = 0; int sign = 1, radix = default_radix, digit; unsigned long k = 0; char c; enum state st = NUM_ST_BEGIN; while ((c = word[k++]) != '\0') { switch (st) { case NUM_ST_BEGIN: if (c == '+' || c == '-') { sign = c == '-' ? -1 : 1; st = NUM_ST_SIGN; } else if (c == '0') { st = NUM_ST_ZERO; } else if ((digit = char2digit(c, radix)) != -1) { acc = digit; /* acc was zero */ st = NUM_ST_DIGITS; } else { return null(); } break; case NUM_ST_SIGN: if (c == '0') { st = NUM_ST_ZERO; } else if ((digit = char2digit(c, radix)) != -1) { acc = digit; /* acc was zero */ st = NUM_ST_DIGITS; } else { return null(); } break; case NUM_ST_ZERO: if (c == 'x' || c == 'X') { radix = 16; st = NUM_ST_RADIX; } else if (c == 'b' || c == 'B') { radix = 2; st = NUM_ST_RADIX; } else if (c == 'd' || c == 'D') { radix = 10; st = NUM_ST_RADIX; } else if (c == 'o' || c == 'O') { radix = 8; st = NUM_ST_RADIX; } else if ((digit = char2digit(c, radix)) != -1) { acc = digit; /* acc was zero */ st = NUM_ST_DIGITS; } else { return null(); } break; case NUM_ST_RADIX: st = NUM_ST_DIGITS; case NUM_ST_DIGITS: if ((digit = char2digit(c, radix)) != -1) { acc = acc * radix + digit; } else { return null(); } } } return wrap_number(sign * acc); }