Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  safe_ultostr.c

  Sprache: C
 

/*++
/* NAME
/* safe_ultostr 3
/* SUMMARY
/* convert unsigned long to safe string
/* SYNOPSIS
/* #include <safe_ultostr.h>
/*
/* char *safe_ultostr(result, ulval, base, padlen, padchar)
/* VSTRING *result;
/* unsigned long ulval;
/* int base;
/* int padlen;
/* int padchar;
/*
/* unsigned long safe_strtoul(start, end, base)
/* const char *start;
/* char **end;
/* int base;
/* DESCRIPTION
/* The functions in this module perform conversions between
/* unsigned long values and "safe" alphanumerical strings
/* (strings with digits, uppercase letters and lowercase
/* letters, but without the vowels AEIOUaeiou). Specifically,
/* the characters B-Z represent the numbers 10-30, and b-z
/* represent 31-51.
/*
/* safe_ultostr() converts an unsigned long value to a safe
/* alphanumerical string. This is the reverse of safe_strtoul().
/*
/* safe_strtoul() implements similar functionality as strtoul()
/* except that it uses a safe alphanumerical string as input,
/* and that it supports no signs or 0/0x prefixes.
/*
/* Arguments:
/* .IP result
/* Buffer for storage of the result of conversion to string.
/* .IP ulval
/* Unsigned long value.
/* .IP base
/* Value between 2 and 52 inclusive.
/* .IP padlen
/* .IP padchar
/* Left-pad a short result with padchar characters to the
/* specified length.  Specify padlen=0 to disable padding.
/* .IP start
/* Pointer to the first character of the string to be converted.
/* .IP end
/* On return, pointer to the first character not in the input
/* alphabet, or to the string terminator.
/* DIAGNOSTICS
/* Fatal: out of memory.
/*
/* safe_strtoul() returns (0, EINVAL) when no conversion could
/* be performed, and (ULONG_MAX, ERANGE) in case of overflow.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/


/* System library. */

#include <sys_defs.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
#include <ctype.h>

/* Utility library. */

#include <msg.h>
#include <vstring.h>
#include <mymalloc.h>

/* Global library. */

#include <safe_ultostr.h>

/* Application-specific. */

#define STR vstring_str
#define END vstring_end
#define SWAP(type, a, b) { type temp; temp = a; a = b; b = temp; }

static unsigned char safe_chars[] =
"0123456789BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz";

#define SAFE_MAX_BASE (sizeof(safe_chars) - 1)
#define SAFE_MIN_BASE (2)

/* safe_ultostr - convert unsigned long to safe alphanumerical string */

char   *safe_ultostr(VSTRING *buf, unsigned long ulval, int base,
               int padlen, int padchar)
{
    const char *myname = "safe_ultostr";
    char   *start;
    char   *last;
    int     i;

    /*
     * Sanity check.
     */

    if (base < SAFE_MIN_BASE || base > SAFE_MAX_BASE)
 msg_panic("%s: bad base: %d", myname, base);

    /*
     * First accumulate the result, backwards.
     */

    VSTRING_RESET(buf);
    while (ulval != 0) {
 VSTRING_ADDCH(buf, safe_chars[ulval % base]);
 ulval /= base;
    }
    while (VSTRING_LEN(buf) < padlen)
 VSTRING_ADDCH(buf, padchar);
    VSTRING_TERMINATE(buf);

    /*
     * Then, reverse the result.
     */

    start = STR(buf);
    last = END(buf) - 1;
    for (i = 0; i < VSTRING_LEN(buf) / 2; i++)
 SWAP(int, start[i], last[-i]);
    return (STR(buf));
}

/* safe_strtoul - convert safe alphanumerical string to unsigned long */

unsigned long safe_strtoul(const char *start, char **end, int base)
{
    const char *myname = "safe_strtoul";
    static unsigned char *char_map = 0;
    unsigned char *cp;
    unsigned long sum;
    unsigned long div_limit;
    unsigned long mod_limit;
    int     char_val;

    /*
     * Sanity check.
     */

    if (base < SAFE_MIN_BASE || base > SAFE_MAX_BASE)
 msg_panic("%s: bad base: %d", myname, base);

    /*
     * One-time initialization. Assume 8-bit bytes.
     */

    if (char_map == 0) {
 char_map = (unsigned char *) mymalloc(256);
 for (char_val = 0; char_val < 256; char_val++)
     char_map[char_val] = SAFE_MAX_BASE;
 for (char_val = 0; char_val < SAFE_MAX_BASE; char_val++)
     char_map[safe_chars[char_val]] = char_val;
    }

    /*
     * Per-call initialization.
     */

    sum = 0;
    div_limit = ULONG_MAX / base;
    mod_limit = ULONG_MAX % base;

    /*
     * Skip leading whitespace. We don't implement sign/base prefixes.
     */

    if (end)
 *end = (char *) start;
    while (ISSPACE(*start))
 ++start;

    /*
     * Start the conversion.
     */

    errno = 0;
    for (cp = (unsigned char *) start; (char_val = char_map[*cp]) < base; cp++) {
 /* Return (ULONG_MAX, ERANGE) if the result is too large. */
 if (sum > div_limit
     || (sum == div_limit && char_val > mod_limit)) {
     sum = ULONG_MAX;
     errno = ERANGE;
     /* Skip "valid" characters, per the strtoul() spec. */
     while (char_map[*++cp] < base)
   /* void */ ;
     break;
 }
 sum = sum * base + char_val;
    }
    /* Return (0, EINVAL) after no conversion. Test moved here 20131209. */
    if (cp == (unsigned char *) start)
 errno = EINVAL;
    else if (end)
 *end = (char *) cp;
    return (sum);
}

#ifdef TEST

 /*
  * Proof-of-concept test program. Read a number from stdin, convert to
  * string, and print the result.
  */

#include <stdio.h>   /* sscanf */
#include <vstream.h>
#include <vstring_vstream.h>

int     main(int unused_argc, char **unused_argv)
{
    VSTRING *buf = vstring_alloc(100);
    char   *junk;
    unsigned long ulval;
    int     base;
    char    ch;
    unsigned long ulval2;

#ifdef MISSING_STRTOUL
#define strtoul strtol
#endif

    /*
     * Hard-coded string-to-number test.
     */

    ulval2 = safe_strtoul("  ", &junk, 10);
    if (*junk == 0 || errno != EINVAL)
 msg_warn("input=' ' result=%lu errno=%m", ulval2);

    /*
     * Configurable number-to-string-to-number test.
     */

    while (vstring_get_nonl(buf, VSTREAM_IN) != VSTREAM_EOF) {
 ch = 0;
 if (sscanf(STR(buf), "%lu %d%c", &ulval, &base, &ch) != 2 || ch) {
     msg_warn("bad input %s", STR(buf));
 } else {
     (void) safe_ultostr(buf, ulval, base, 5'0');
     vstream_printf("%lu = %s\n", ulval, STR(buf));
     ulval2 = safe_strtoul(STR(buf), &junk, base);
     if (*junk || (ulval2 == ULONG_MAX && errno == ERANGE))
  msg_warn("%s: %m", STR(buf));
     if (ulval2 != ulval)
  msg_warn("%lu != %lu", ulval2, ulval);
 }
 vstream_fflush(VSTREAM_OUT);
    }
    vstring_free(buf);
    return (0);
}

#endif

Messung V0.5 in Prozent
C=75 H=95 G=85

¤ Dauer der Verarbeitung: 0.27 Sekunden  (vorverarbeitet am  2026-08-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=752002