diff options
Diffstat (limited to 'libbb/pw_ascii64.c')
-rw-r--r-- | libbb/pw_ascii64.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/libbb/pw_ascii64.c b/libbb/pw_ascii64.c new file mode 100644 index 000000000..3993932ca --- /dev/null +++ b/libbb/pw_ascii64.c | |||
@@ -0,0 +1,91 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Utility routines. | ||
4 | * | ||
5 | * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> | ||
6 | * | ||
7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
8 | */ | ||
9 | |||
10 | /* Returns >=64 for invalid chars */ | ||
11 | int FAST_FUNC a2i64(char c) | ||
12 | { | ||
13 | unsigned char ch = c; | ||
14 | if (ch >= 'a') | ||
15 | /* "a..z" to 38..63 */ | ||
16 | /* anything after "z": positive int >= 64 */ | ||
17 | return (ch - 'a' + 38); | ||
18 | |||
19 | if (ch > 'Z') | ||
20 | /* after "Z" but before "a": positive byte >= 64 */ | ||
21 | return ch; | ||
22 | |||
23 | if (ch >= 'A') | ||
24 | /* "A..Z" to 12..37 */ | ||
25 | return (ch - 'A' + 12); | ||
26 | |||
27 | if (ch > '9') | ||
28 | return 64; | ||
29 | |||
30 | /* "./0123456789" to 0,1,2..11 */ | ||
31 | /* anything before "." becomes positive byte >= 64 */ | ||
32 | return (unsigned char)(ch - '.'); | ||
33 | } | ||
34 | |||
35 | /* 0..63 -> | ||
36 | * "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; | ||
37 | */ | ||
38 | int FAST_FUNC i2a64(int i) | ||
39 | { | ||
40 | i &= 0x3f; | ||
41 | |||
42 | i += '.'; | ||
43 | /* the above maps 0..11 to "./0123456789": | ||
44 | * ACSII codes of "./" are ('0'-2) and ('0'-1) */ | ||
45 | |||
46 | if (i > '9') | ||
47 | i += ('A' - '9' - 1); | ||
48 | if (i > 'Z') | ||
49 | i += ('a' - 'Z' - 1); | ||
50 | return i; | ||
51 | } | ||
52 | |||
53 | char* FAST_FUNC | ||
54 | num2str64_lsb_first(char *s, unsigned v, int n) | ||
55 | { | ||
56 | while (--n >= 0) { | ||
57 | *s++ = i2a64(v); | ||
58 | v >>= 6; | ||
59 | } | ||
60 | return s; | ||
61 | } | ||
62 | |||
63 | static void | ||
64 | num2str64_4chars_msb_first(char *s, unsigned v) | ||
65 | { | ||
66 | *s++ = i2a64(v >> 18); /* bits 23..18 */ | ||
67 | *s++ = i2a64(v >> 12); /* bits 17..12 */ | ||
68 | *s++ = i2a64(v >> 6); /* bits 11..6 */ | ||
69 | *s = i2a64(v); /* bits 5..0 */ | ||
70 | } | ||
71 | |||
72 | int FAST_FUNC crypt_make_rand64encoded(char *p, int cnt /*, int x */) | ||
73 | { | ||
74 | /* was: x += ... */ | ||
75 | unsigned x = getpid() + monotonic_us(); | ||
76 | do { | ||
77 | /* x = (x*1664525 + 1013904223) % 2^32 generator is lame | ||
78 | * (low-order bit is not "random", etc...), | ||
79 | * but for our purposes it is good enough */ | ||
80 | x = x*1664525 + 1013904223; | ||
81 | /* BTW, Park and Miller's "minimal standard generator" is | ||
82 | * x = x*16807 % ((2^31)-1) | ||
83 | * It has no problem with visibly alternating lowest bit | ||
84 | * but is also weak in cryptographic sense + needs div, | ||
85 | * which needs more code (and slower) on many CPUs */ | ||
86 | *p++ = i2a64(x >> 16); | ||
87 | *p++ = i2a64(x >> 22); | ||
88 | } while (--cnt); | ||
89 | *p = '\0'; | ||
90 | return x; | ||
91 | } | ||