int encode_number(char *msg, char *no) { unsigned int i; int digit; setbits(msg, 0, 2, 0); setbits(msg, 2, 8, strlen(no)); for(i=0;i<strlen(no);i++) setbits(msg,10+i*4, 4, encode_digit(no[i])); return (10+i*4+7)/8; }
/* Punycode encoder, RFC 3492 section 6.3. The algorithm is * sufficiently bizarre that it's not really worth trying to explain * here. */ static gboolean punycode_encode (const gchar *input_utf8, gsize input_utf8_length, GString *output) { guint delta, handled_chars, num_basic_chars, bias, j, q, k, t, digit; gunichar n, m, *input; glong input_length; gboolean success = FALSE; /* Convert from UTF-8 to Unicode code points */ input = g_utf8_to_ucs4 (input_utf8, input_utf8_length, NULL, &input_length, NULL); if (!input) return FALSE; /* Copy basic chars */ for (j = num_basic_chars = 0; j < input_length; j++) { if (PUNYCODE_IS_BASIC (input[j])) { g_string_append_c (output, g_ascii_tolower (input[j])); num_basic_chars++; } } if (num_basic_chars) g_string_append_c (output, '-'); handled_chars = num_basic_chars; /* Encode non-basic chars */ delta = 0; bias = PUNYCODE_INITIAL_BIAS; n = PUNYCODE_INITIAL_N; while (handled_chars < input_length) { /* let m = the minimum {non-basic} code point >= n in the input */ for (m = G_MAXUINT, j = 0; j < input_length; j++) { if (input[j] >= n && input[j] < m) m = input[j]; } if (m - n > (G_MAXUINT - delta) / (handled_chars + 1)) goto fail; delta += (m - n) * (handled_chars + 1); n = m; for (j = 0; j < input_length; j++) { if (input[j] < n) { if (++delta == 0) goto fail; } else if (input[j] == n) { q = delta; for (k = PUNYCODE_BASE; ; k += PUNYCODE_BASE) { if (k <= bias) t = PUNYCODE_TMIN; else if (k >= bias + PUNYCODE_TMAX) t = PUNYCODE_TMAX; else t = k - bias; if (q < t) break; digit = t + (q - t) % (PUNYCODE_BASE - t); g_string_append_c (output, encode_digit (digit)); q = (q - t) / (PUNYCODE_BASE - t); } g_string_append_c (output, encode_digit (q)); bias = adapt (delta, handled_chars + 1, handled_chars == num_basic_chars); delta = 0; handled_chars++; } } delta++; n++; } success = TRUE; fail: g_free (input); return success; }
enum punycode_status punycode_encode( punycode_uint input_length, const punycode_uint input[], const unsigned char case_flags[], punycode_uint *output_length, char output[] ) { punycode_uint n, delta, h, b, out, max_out, bias, j, m, q, k, t; /* Initialize the state: */ n = initial_n; delta = out = 0; max_out = *output_length; bias = initial_bias; /* Handle the basic code points: */ for (j = 0; j < input_length; ++j) { if (basic(input[j])) { if (max_out - out < 2) return punycode_big_output; output[out++] = (char) (case_flags ? encode_basic(input[j], case_flags[j]) : input[j]); } /* else if (input[j] < n) return punycode_bad_input; */ /* (not needed for Punycode with unsigned code points) */ } h = b = out; /* h is the number of code points that have been handled, b is the */ /* number of basic code points, and out is the number of characters */ /* that have been output. */ if (b > 0) output[out++] = delimiter; /* Main encoding loop: */ while (h < input_length) { /* All non-basic code points < n have been */ /* handled already. Find the next larger one: */ for (m = maxint, j = 0; j < input_length; ++j) { /* if (basic(input[j])) continue; */ /* (not needed for Punycode) */ if (input[j] >= n && input[j] < m) m = input[j]; } /* Increase delta enough to advance the decoder's */ /* <n,i> state to <m,0>, but guard against overflow: */ if (m - n > (maxint - delta) / (h + 1)) return punycode_overflow; delta += (m - n) * (h + 1); n = m; for (j = 0; j < input_length; ++j) { /* Punycode does not need to check whether input[j] is basic: */ if (input[j] < n /* || basic(input[j]) */ ) { if (++delta == 0) return punycode_overflow; } if (input[j] == n) { /* Represent delta as a generalized variable-length integer: */ for (q = delta, k = base; ; k += base) { if (out >= max_out) return punycode_big_output; t = k <= bias /* + tmin */ ? tmin : /* +tmin not needed */ k >= bias + tmax ? tmax : k - bias; if (q < t) break; output[out++] = encode_digit(t + (q - t) % (base - t), 0); q = (q - t) / (base - t); } output[out++] = encode_digit(q, case_flags && case_flags[j]); bias = adapt(delta, h + 1, h == b); delta = 0; ++h; } } ++delta, ++n; } *output_length = out; return punycode_success; }
int punycode_encode( unsigned int input_length, const DWORD input[], unsigned int *output_length, char output[] ) { DWORD n, delta, h, b, out, max_out, bias, j, m, q, k, t; /* Initialize the state: */ n = initial_n; delta = out = 0; max_out = *output_length; bias = initial_bias; /* Handle the basic code points: */ for (j = 0; j < input_length; ++j) { if ( basic( input[j] ) ) { if (max_out - out < 2) return XCODE_BAD_ARGUMENT_ERROR; output[out++] = (char)input[j]; } /* else if (input[j] < n) return XCODE_BAD_ARGUMENT_ERROR; */ /* (not needed for AMC-ACE-Z with unsigned code points) */ } h = b = out; /* h is the number of code points that have been handled, b is the */ /* number of basic code points, and out is the number of characters */ /* that have been output. */ if (b > 0) output[out++] = delimiter; /* Main encoding loop: */ while (h < input_length) { /* All non-basic code points < n have been */ /* handled already. Find the next larger one: */ for (m = maxint, j = 0; j < input_length; ++j) { /* if (basic(input[j])) continue; */ /* (not needed for AMC-ACE-Z) */ if (input[j] >= n && input[j] < m) m = input[j]; } /* Increase delta enough to advance the decoder's */ /* <n,i> state to <m,0>, but guard against overflow: */ if (m - n > (maxint - delta) / (h + 1)) return XCODE_BUFFER_OVERFLOW_ERROR; delta += (m - n) * (h + 1); n = m; for (j = 0; j < input_length; ++j) { #if 0 if (input[j] < n || basic(input[j])) { if (++delta == 0) return XCODE_BUFFER_OVERFLOW_ERROR; } #endif /* AMC-ACE-Z can use this simplified version instead: */ if (input[j] < n && ++delta == 0) return XCODE_BUFFER_OVERFLOW_ERROR; if (input[j] == n) { /* Represent delta as a generalized variable-length integer: */ for (q = delta, k = base; ; k += base) { if (out >= max_out) return XCODE_BAD_ARGUMENT_ERROR; t = k <= bias ? tmin : k - bias >= tmax ? tmax : k - bias; if (q < t) break; output[out++] = encode_digit(t + (q - t) % (base - t), 0); q = (q - t) / (base - t); } output[out++] = encode_digit(q, 0); /* Adapt the bias: */ delta = h == b ? delta / damp : delta >> 1; delta += delta / (h + 1); for (bias = 0; delta > cutoff; bias += base) delta /= lobase; bias += (lobase + 1) * delta / (delta + skew); delta = 0; ++h; } } ++delta; ++n; } *output_length = (unsigned int) out; return XCODE_SUCCESS; }