Skip to content

Commit

Permalink
Added base64 encoding/decoding capabilities.
Browse files Browse the repository at this point in the history
The bracket mappings `[6` and `]6` map to base64 encoding and
decoding.
  • Loading branch information
Benoit Mortgat committed Feb 20, 2012
1 parent e39b350 commit 9695c84
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.markdown
Expand Up @@ -20,6 +20,7 @@ Decoding/Encoding XML entities, URLs, C-strings
Use `[` for encoding and `]` for decoding, followed by

* `x` for XML entities,
* `6` for base64,
* `u` for URL-encoding and
* `y` for C strings. (`[c` and `]c` are already used for jumping through changes in diff mode).

Expand Down
10 changes: 10 additions & 0 deletions doc/unimpaired.txt
Expand Up @@ -104,6 +104,16 @@ Mnenomic: encoding always comes before decoding; "[" always comes before "]".
]yy
{Visual}]y

*[6* *[66* *v_[6*
[6{motion} Base64 encode.
[66 foo bar => Zm9vIGJhcg==
{Visual}[6

*]6* *]66* *v_]6*
]6{motion} Base64 decode
]66 Input length must be a multiple of 4.
{Visual}]6

TODO *unimpaired-todo*

Avoid munging null characters when encoding and decoding.
Expand Down
61 changes: 61 additions & 0 deletions plugin/unimpaired.vim
Expand Up @@ -186,6 +186,65 @@ function! s:UrlDecode(str)
return substitute(str,'%\(\x\x\)','\=nr2char("0x".submatch(1))','g')
endfunction

let g:unimpaired_base64_chars = map(range(char2nr('A'),char2nr('Z')),'nr2char(v:val)')
\ + map(range(char2nr('a'),char2nr('z')),'nr2char(v:val)')
\ + map(range(char2nr('0'),char2nr('9')),'nr2char(v:val)')
\ + ['+','/']

let g:unimpaired_base64_filler = '='
let g:unimpaired_base64_reverse_map = {}
let s:pos = 0
for s:char in g:unimpaired_base64_chars
let g:unimpaired_base64_reverse_map[s:char] = s:pos
let s:pos = s:pos + 1
endfor
unlet s:pos

function! s:Base64Encode(str)
" Respect current file encoding
let to_be_encoded=a:str
let encoded = ''
while len(to_be_encoded) > 2
let encoded .= g:unimpaired_base64_chars[char2nr(to_be_encoded[0])/4]
\ . g:unimpaired_base64_chars[16*(char2nr(to_be_encoded[0])%4 )+char2nr(to_be_encoded[1])/16]
\ . g:unimpaired_base64_chars[4 *(char2nr(to_be_encoded[1])%16)+char2nr(to_be_encoded[2])/64]
\ . g:unimpaired_base64_chars[char2nr(to_be_encoded[2])%64]
let to_be_encoded = to_be_encoded[3:]
endwhile
if len(to_be_encoded) == 2
let encoded .= g:unimpaired_base64_chars[char2nr(to_be_encoded[0])/4]
\ . g:unimpaired_base64_chars[16*(char2nr(to_be_encoded[0])%4 )+char2nr(to_be_encoded[1])/16]
\ . g:unimpaired_base64_chars[4 *(char2nr(to_be_encoded[1])%16)]
\ . g:unimpaired_base64_filler
elseif len(to_be_encoded) == 1
let encoded .= g:unimpaired_base64_chars[char2nr(to_be_encoded[0])/4]
\ . g:unimpaired_base64_chars[16*(char2nr(to_be_encoded[0])%4 )]
\ . g:unimpaired_base64_filler
\ . g:unimpaired_base64_filler
endif
return encoded
endfunction

function! s:Base64Decode(str)
let to_be_decoded=a:str
let decoded=''
while len(to_be_decoded) % 4 == 0
let decoded .= nr2char( 4 * (g:unimpaired_base64_reverse_map[to_be_decoded[0]] )
\ + (g:unimpaired_base64_reverse_map[to_be_decoded[1]] / 16 )
\)
if to_be_decoded[2] !=# g:unimpaired_base64_filler
let decoded .= nr2char(16 * (g:unimpaired_base64_reverse_map[to_be_decoded[1]] % 16) + (g:unimpaired_base64_reverse_map[to_be_decoded[2]]/4))
if to_be_decoded[3] !=# g:unimpaired_base64_filler
let decoded .= nr2char(64 * (g:unimpaired_base64_reverse_map[to_be_decoded[2]] % 4) + g:unimpaired_base64_reverse_map[to_be_decoded[3]])
endif
endif
let to_be_decoded = to_be_decoded[4:]
if empty(to_be_decoded)
return decoded
endif
endwhile
endfunction

" HTML entities {{{2

let g:unimpaired_html_entities = {
Expand Down Expand Up @@ -331,6 +390,8 @@ call s:MapTransform('UrlEncode','[u')
call s:MapTransform('UrlDecode',']u')
call s:MapTransform('XmlEncode','[x')
call s:MapTransform('XmlDecode',']x')
call s:MapTransform('Base64Encode','[6')
call s:MapTransform('Base64Decode',']6')

" }}}1

Expand Down

0 comments on commit 9695c84

Please sign in to comment.