diff options
author | Ori Bernstein <ori@eigenstate.org> | 2021-07-03 20:03:17 +0000 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2021-07-03 20:03:17 +0000 |
commit | e934530ee4512f033952e4efa80a80058607b741 (patch) | |
tree | 2bde95220e1d5e26000286a7f04b93431d8121c8 /sys/src/libc | |
parent | c848ca62673689df20e7fef74d1d5180f37fcea6 (diff) |
libc: add encode(2) variants for custom alphabets
There are a number of alphabets in common use for base32
and base64 encoding, such as url-safe encodings.
This adds support for passing a function to encode into
arbitary alphabets.
Diffstat (limited to 'sys/src/libc')
-rw-r--r-- | sys/src/libc/port/u32.c | 50 | ||||
-rw-r--r-- | sys/src/libc/port/u64.c | 36 |
2 files changed, 55 insertions, 31 deletions
diff --git a/sys/src/libc/port/u32.c b/sys/src/libc/port/u32.c index 9ad9eb781..a7abdc012 100644 --- a/sys/src/libc/port/u32.c +++ b/sys/src/libc/port/u32.c @@ -25,7 +25,7 @@ dec32chr(int c) } int -dec32(uchar *dest, int ndest, char *src, int nsrc) +dec32x(uchar *dest, int ndest, char *src, int nsrc, int (*chr)(int)) { uchar *start; int i, j, u[8]; @@ -35,7 +35,7 @@ dec32(uchar *dest, int ndest, char *src, int nsrc) start = dest; while(nsrc>=8){ for(i=0; i<8; i++){ - j = dec32chr(src[i]); + j = chr(src[i]); if(j < 0) j = 0; u[i] = j; @@ -52,7 +52,7 @@ dec32(uchar *dest, int ndest, char *src, int nsrc) if(nsrc == 1 || nsrc == 3 || nsrc == 6) return -1; for(i=0; i<nsrc; i++){ - j = dec32chr(src[i]); + j = chr(src[i]); if(j < 0) j = 0; u[i] = j; @@ -73,7 +73,7 @@ out: } int -enc32(char *dest, int ndest, uchar *src, int nsrc) +enc32x(char *dest, int ndest, uchar *src, int nsrc, int (*chr)(int)) { char *start; int j; @@ -83,50 +83,62 @@ enc32(char *dest, int ndest, uchar *src, int nsrc) start = dest; while(nsrc>=5){ j = (0x1f & (src[0]>>3)); - *dest++ = enc32chr(j); + *dest++ = chr(j); j = (0x1c & (src[0]<<2)) | (0x03 & (src[1]>>6)); - *dest++ = enc32chr(j); + *dest++ = chr(j); j = (0x1f & (src[1]>>1)); - *dest++ = enc32chr(j); + *dest++ = chr(j); j = (0x10 & (src[1]<<4)) | (0x0f & (src[2]>>4)); - *dest++ = enc32chr(j); + *dest++ = chr(j); j = (0x1e & (src[2]<<1)) | (0x01 & (src[3]>>7)); - *dest++ = enc32chr(j); + *dest++ = chr(j); j = (0x1f & (src[3]>>2)); - *dest++ = enc32chr(j); + *dest++ = chr(j); j = (0x18 & (src[3]<<3)) | (0x07 & (src[4]>>5)); - *dest++ = enc32chr(j); + *dest++ = chr(j); j = (0x1f & (src[4])); - *dest++ = enc32chr(j); + *dest++ = chr(j); src += 5; nsrc -= 5; } if(nsrc){ j = (0x1f & (src[0]>>3)); - *dest++ = enc32chr(j); + *dest++ = chr(j); j = (0x1c & (src[0]<<2)); if(nsrc == 1) goto out; j |= (0x03 & (src[1]>>6)); - *dest++ = enc32chr(j); + *dest++ = chr(j); j = (0x1f & (src[1]>>1)); - *dest++ = enc32chr(j); + *dest++ = chr(j); j = (0x10 & (src[1]<<4)); if(nsrc == 2) goto out; j |= (0x0f & (src[2]>>4)); - *dest++ = enc32chr(j); + *dest++ = chr(j); j = (0x1e & (src[2]<<1)); if(nsrc == 3) goto out; j |= (0x01 & (src[3]>>7)); - *dest++ = enc32chr(j); + *dest++ = chr(j); j = (0x1f & (src[3]>>2)); - *dest++ = enc32chr(j); + *dest++ = chr(j); j = (0x18 & (src[3]<<3)); out: - *dest++ = enc32chr(j); + *dest++ = chr(j); } *dest = 0; return dest-start; } + +int +enc32(char *dest, int ndest, uchar *src, int nsrc) +{ + return enc32x(dest, ndest, src, nsrc, enc32chr); +} + +int +dec32(uchar *dest, int ndest, char *src, int nsrc) +{ + return dec32x(dest, ndest, src, nsrc, dec32chr); +} diff --git a/sys/src/libc/port/u64.c b/sys/src/libc/port/u64.c index 44f716fbe..5be0142b8 100644 --- a/sys/src/libc/port/u64.c +++ b/sys/src/libc/port/u64.c @@ -30,7 +30,7 @@ dec64chr(int c) } int -dec64(uchar *out, int lim, char *in, int n) +dec64x(uchar *out, int lim, char *in, int n, int (*chr)(int)) { ulong b24; uchar *start = out; @@ -40,7 +40,7 @@ dec64(uchar *out, int lim, char *in, int n) b24 = 0; i = 0; while(n-- > 0){ - c = dec64chr(*in++); + c = chr(*in++); if(c < 0) continue; switch(i){ @@ -84,7 +84,7 @@ exhausted: } int -enc64(char *out, int lim, uchar *in, int n) +enc64x(char *out, int lim, uchar *in, int n, int (*chr)(int)) { int i; ulong b24; @@ -97,10 +97,10 @@ enc64(char *out, int lim, uchar *in, int n) b24 |= *in++; if(out + 4 >= e) goto exhausted; - *out++ = enc64chr(b24>>18); - *out++ = enc64chr((b24>>12)&0x3f); - *out++ = enc64chr((b24>>6)&0x3f); - *out++ = enc64chr(b24&0x3f); + *out++ = chr(b24>>18); + *out++ = chr((b24>>12)&0x3f); + *out++ = chr((b24>>6)&0x3f); + *out++ = chr(b24&0x3f); } switch(n%3){ @@ -109,17 +109,17 @@ enc64(char *out, int lim, uchar *in, int n) b24 |= *in<<8; if(out + 4 >= e) goto exhausted; - *out++ = enc64chr(b24>>18); - *out++ = enc64chr((b24>>12)&0x3f); - *out++ = enc64chr((b24>>6)&0x3f); + *out++ = chr(b24>>18); + *out++ = chr((b24>>12)&0x3f); + *out++ = chr((b24>>6)&0x3f); *out++ = '='; break; case 1: b24 = *in<<16; if(out + 4 >= e) goto exhausted; - *out++ = enc64chr(b24>>18); - *out++ = enc64chr((b24>>12)&0x3f); + *out++ = chr(b24>>18); + *out++ = chr((b24>>12)&0x3f); *out++ = '='; *out++ = '='; break; @@ -128,3 +128,15 @@ exhausted: *out = 0; return out - start; } + +int +enc64(char *out, int lim, uchar *in, int n) +{ + return enc64x(out, lim, in, n, enc64chr); +} + +int +dec64(uchar *out, int lim, char *in, int n) +{ + return dec64x(out, lim, in, n, dec64chr); +} |