base32core.tcl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 namespace ::base32::core {}
00013
00014
00015
00016
00017 ret ::base32::core::define (type map , type fv , type bv , type iv) {
00018 variable bits
00019 upvar 1 $fv forward $bv backward $iv invalid
00020
00021 # bytes - bits - padding - tail | bits - padding - tail
00022 # 0 - 0 - "" - "xxxxxxxx" | 0 - "" - ""
00023 # 1 - 8 - "======" - "xx======" | 3 - "======" - "x======"
00024 # 2 - 16 - "====" - "xxxx====" | 1 - "====" - "x===="
00025 # 3 - 24 - "===" - "xxxxx===" | 4 - "===" - "x==="
00026 # 4 - 32 - "=" - "xxxxxxx=" | 2 - "=" - "x="
00027
00028 array set _ $bits
00029
00030 set invalid "\[^="
00031 set forward {}
00032 set btmp {}
00033
00034 foreach {code char} $map {
00035 set b $_($code)
00036
00037 append invalid [string tolower $char][string toupper $char]
00038
00039 # 5 bit remainder
00040 lappend forward $b $char
00041 lappend btmp [list $char $b]
00042
00043 # 4 bit remainder
00044 if {$code%2} continue
00045 set b [string range $b 0 end-1]
00046 lappend forward ${b}=/4 ${char}===
00047 lappend btmp [list ${char}=== $b]
00048
00049 # 3 bit remainder
00050 if {$code%4} continue
00051 set b [string range $b 0 end-1]
00052 lappend forward ${b}=/3 ${char}======
00053 lappend btmp [list ${char}====== $b]
00054
00055 # 2 bit remainder
00056 if {$code%8} continue
00057 set b [string range $b 0 end-1]
00058 lappend forward ${b}=/2 ${char}=
00059 lappend btmp [list ${char}= $b]
00060
00061 # 1 bit remainder
00062 if {$code%16} continue
00063 set b [string range $b 0 end-1]
00064 lappend forward ${b}=/1 ${char}====
00065 lappend btmp [list ${char}==== $b]
00066 }
00067
00068 set backward {}
00069 foreach item [lsort -index 0 -decreasing $btmp] {
00070 foreach {c b} $item break
00071 lappend backward $c $b
00072 }
00073
00074 append invalid "\]"
00075 return
00076 }
00077
00078 ret ::base32::core::valid (type estring , type pattern , type mv) {
00079 upvar 1 $mv message
00080
00081 if {[string length $estring] % 8} {
00082 set message "Length is not a multiple of 8"
00083 return 0
00084 } elseif {[regexp -indices $pattern $estring where]} {
00085 foreach {s e} $where break
00086 set message "Invalid character at index $s: \"[string index $estring $s]\""
00087 return 0
00088 } elseif {[regexp {(=+)$} $estring -> pad]} {
00089 set padlen [string length $pad]
00090 if {
00091 ($padlen != 6) &&
00092 ($padlen != 4) &&
00093 ($padlen != 3) &&
00094 ($padlen != 1)
00095 } {
00096 set message "Invalid padding of length $padlen"
00097 return 0
00098 }
00099 }
00100
00101 # Remove the brackets and ^= from the pattern, to construct the
00102 # class of valid characters which must not follow the padding.
00103
00104 set badp "=\[[string range $pattern 3 end-1]\]"
00105 if {[regexp -indices $badp $estring where]} {
00106 foreach {s e} $where break
00107 set message "Invalid character at index $s: \"[string index $estring $s]\" (padding found in the middle of the input)"
00108 return 0
00109 }
00110 return 1
00111 }
00112
00113
00114
00115
00116 namespace ::base32::core {
00117 namespace export define valid
00118
00119 variable bits {
00120 0 00000 1 00001 2 00010 3 00011
00121 4 00100 5 00101 6 00110 7 00111
00122 8 01000 9 01001 10 01010 11 01011
00123 12 01100 13 01101 14 01110 15 01111
00124 16 10000 17 10001 18 10010 19 10011
00125 20 10100 21 10101 22 10110 23 10111
00126 24 11000 25 11001 26 11010 27 11011
00127 28 11100 29 11101 30 11110 31 11111
00128 }
00129 }
00130
00131
00132
00133
00134 package provide base32::core 0.1
00135