UNPKG

vanillaaont

Version:

simple all-or-nothing transform in nothing but vanilla js

102 lines (95 loc) 3.3 kB
/** The name of this file is a result of this transform seeming to somehow compress the input but I do not know how. What I mean is...the transform here seems to produce a result that contains less source characters than are actually in the source, and yet perfectly reconstructrs the source. **/ "use strict"; { const vanillaaont = { T,TU,rotate_left_by, rotate_right_by }; const alph = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const dec = "0123456789"; const twomore = "/+!"; const alphabet = alph + dec + alph.toLowerCase() + twomore; const pad = "!"; const initial_rotate = 13; const rotates = alphabet. split(''). reduce( (m,c,i) => ( m[c] = i+1, m ), {} ); try { Object.assign( self, { vanillaaont } ); } catch(e) { module.exports = vanillaaont; } function T( m ) { m = Array.from(m); m.reverse(); let tail_start = m.indexOf('='); let head = m; let tail = []; if ( tail_start >= 0 ) { head = m.slice(0, tail_start); tail = m.slice(tail_start); } m = pad_to_multiple( 65, pad, head ); const b = Array.from(m); let i = -1; while( true ) { const mc = b[i+1]; const rotate_amount = i >= 0 ? rotates[mc] : initial_rotate; console.log(i+1, mc, `rotating from ${i+2} by ${rotate_amount}`); if ( ! rotate_amount ) { throw new TypeError(`This string is not in base 64. We only know how to interpret these symbols: ${alphabet}. You provided this: "${mc}"` ); } if ( i+2 < m.length - 65 ) { const rot_sec = rotate_left_by( rotate_amount, b.slice( i+2, i+67 ) ); b.splice( i+2, 65, ...rot_sec ); } else { break; } i+=1; } b.push(...tail); return b.join(''); } function TU( m ) { m = Array.from(m); const tail_count = m.filter( mc => mc == "=" ).length; const b = Array.from(m); let j = m.length-66; while( j > 0 ) { const mc = b[j-1]; const rotate_amount = j >= 2 ? rotates[mc] : initial_rotate; console.log(j-1, mc, `rotating from ${j} by ${rotate_amount}`); if ( ! rotate_amount ) { throw new TypeError(`This string is not in base 64. We only know how to interpret these symbols: ${alphabet}. You provided this: "${mc}"` ); } const rot_sec = rotate_right_by( rotate_amount, b.slice( j, j+65 ) ); b.splice( j, 65, ...rot_sec ); j -= 1; } const result = b.filter( mc => mc !== '!' ); result.push( ...Array(tail_count+1).join('=') ); result.reverse(); return result.join(''); } function rotate_right_by( amount, array ) { let head = array.slice( array.length - amount ); const tail = array.slice(0,array.length - amount); head = head.concat(tail); return head; } function rotate_left_by( amount, array ) { let head = array.slice( amount ); const tail = array.slice(0,amount); head = head.concat(tail); return head; } function pad_to_multiple( multiplier, pad_char, array ) { const padding_required = multiplier - (array.length % multiplier); let padded = Array.from(array); if ( padding_required ) { const padding = new Array( padding_required + 1 ).join(pad_char).split(''); padded = padded.concat( padding ); } return padded; } }