示例#1
0
文件: sms.c 项目: checko/sxx-ril
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;
}
示例#2
0
/* 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;
}
示例#3
0
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;
}
示例#4
0
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;
}