Repository: gabemart/hipku
Branch: master
Commit: e4992fc30305
Files: 8
Total size: 29.1 KB
Directory structure:
gitextract_pxxfoasq/
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── index.js
├── package.json
└── test/
└── spec/
├── allVersions.spec.js
└── currentVersion.spec.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
TODO.txt
node_modules/
================================================
FILE: .npmignore
================================================
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2014 Gabriel Martin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# Hipku
A tiny javascript library to encode IPv6 and IPv4 addresses as haiku.
For full documentation and a working demo, check out https://gabrielbrady.com/projects/hipku
## Installation
Install with `npm install hipku`. `index.js` can also be used directly in the browser.
## Usage
To encode `127.0.0.1` or `::1` call `Hipku.encode('127.0.0.1')` or `Hipku.encode('::1')`. IPv4 addresses must have octets separated by a `.` period character and IPv6 addresses must have hextets separated by a `:` colon character.
When decoding a hipku, such as:
The weary red dove
fights in the empty tundra.
Jasmine petals dance.
the lines can be separated either by the newline character `\n` or by a space. Both will produce the same result.
Hipku.decode('The weary red dove\nfights in the empty tundra.\nJasmine petals dance.');
> "254.53.93.114"
Hipku.decode('The weary red dove fights in the empty tundra. Jasmine petals dance.');
> "254.53.93.114"
### Node.js
var hipku = require('hipku');
hipku.encode('127.0.0.1');
hipku.decode('The weary red dove fights in the empty tundra. Jasmine petals dance.');
================================================
FILE: index.js
================================================
/*
** Hipku version 0.0.2
** Copyright (c) Gabriel Martin 2014
** All rights reserved
** Available under the MIT license
** http://gabrielmartin.net/projects/hipku
*/
;
var Hipku = (function() {
/*
** ##############
** Public Methods
** ##############
*/
/*
** Object holds all public methods and is returned by the module
*/
var publicMethods = {};
/*
** Public method to encode IP Addresses as haiku
*/
var encode = function(ip) {
var ipv6, decimalOctetArray, factoredOctetArray, encodedWordArray,
haikuText;
ipv6 = ipIsIpv6(ip);
decimalOctetArray = splitIp(ip, ipv6);
factoredOctetArray = factorOctets(decimalOctetArray, ipv6);
encodedWordArray = encodeWords(factoredOctetArray, ipv6);
haikuText = writeHaiku(encodedWordArray, ipv6);
return haikuText;
};
/*
** Public method to decode haiku into IP Addresses
*/
var decode = function(haiku) {
var wordArray, ipv6, factorArray, octetArray, ipString;
wordArray = splitHaiku(haiku);
ipv6 = haikuIsIpv6(wordArray);
factorArray = getFactors(wordArray, ipv6);
octetArray = getOctets(factorArray, ipv6);
ipString = getIpString(octetArray, ipv6);
return ipString;
};
/*
** Attach the public methods to the return object
*/
publicMethods.encode = encode;
publicMethods.decode = decode;
/*
** #############################
** Helper functions for encoding
** #############################
*/
function ipIsIpv6(ip) {
if (ip.indexOf(':') != -1) { return true; }
else if (ip.indexOf('.') != -1) { return false; }
else {
throw new Error('Formatting error in IP Address input.' +
' ' + 'Contains neither ":" or "."');
}
}
function splitIp(ip, ipv6) {
var octetArray, separator, v6Base, numOctets, decimalOctetArray;
octetArray = [];
decimalOctetArray = [];
v6Base = 16;
if (ipv6) {
separator = ':';
numOctets = 8;
} else {
separator = '.';
numOctets = 4;
}
/*
** Remove newline and space characters
*/
ip = ip.replace(/[\n\ ]/g, '');
octetArray = ip.split(separator);
/*
** If IPv6 address is in abbreviated format, we need to replace missing octets with 0
*/
if (octetArray.length < numOctets) {
if (ipv6) {
var numMissingOctets = (numOctets - octetArray.length);
octetArray = padOctets(octetArray, numMissingOctets);
} else {
throw new Error('Formatting error in IP Address input.' +
' ' + 'IPv4 address has fewer than 4 octets.');
}
}
/*
** Conter IPv6 addresses from hex to decimal
*/
if (ipv6) {
for (var i = 0; i < octetArray.length; i++) {
decimalOctetArray[i] = parseInt(octetArray[i], v6Base);
}
} else {
decimalOctetArray = octetArray;
}
return decimalOctetArray;
}
/*
** If IPv6 is abbreviated, pad with appropriate number of 0 octets
*/
function padOctets(octetArray, numMissingOctets) {
var paddedOctet, aLength;
paddedOctet = 0;
aLength = octetArray.length;
/*
** If the first or last octets are blank, zero them
*/
if (octetArray[0] === '') {
octetArray[0] = paddedOctet;
}
if (octetArray[aLength - 1] === '') {
octetArray[aLength - 1] = paddedOctet;
}
/*
** Check the rest of the array for blank octets and pad as needed
*/
for (var i = 0; i < aLength; i++) {
if (octetArray[i] === '') {
octetArray[i] = paddedOctet;
for (var j = 0; j < numMissingOctets; j++) {
octetArray.splice(i, 0, paddedOctet);
}
}
}
return octetArray;
}
/*
** Convert each decimal octet into a factor of the divisor (16 or 256)
** and a remainder
*/
function factorOctets(octetArray, ipv6) {
var divisor, factoredOctetArray;
factoredOctetArray = [];
if (ipv6) {
divisor = 256;
} else {
divisor = 16;
}
for (var i = 0; i < octetArray.length; i++) {
var octetValue, factor1, factor2;
octetValue = octetArray[i];
factor1 = octetArray[i] % divisor;
octetValue = octetValue - factor1;
factor2 = octetValue / divisor;
factoredOctetArray.push(factor2);
factoredOctetArray.push(factor1);
}
return factoredOctetArray;
}
function encodeWords(factorArray, ipv6) {
var key, encodedWordArray;
encodedWordArray = [];
key = getKey(ipv6);
for (var i = 0; i < factorArray.length; i++) {
var dict;
dict = key[i];
encodedWordArray[i] = dict[factorArray[i]];
}
return encodedWordArray;
}
/*
** Return an array of dictionaries representing the correct word
** order for the haiku
*/
function getKey(ipv6) {
var key;
if (ipv6) {
key = [ adjectives,
nouns,
adjectives,
nouns,
verbs,
adjectives,
adjectives,
adjectives,
adjectives,
adjectives,
nouns,
adjectives,
nouns,
verbs,
adjectives,
nouns ];
} else {
key = [ animalAdjectives,
animalColors,
animalNouns,
animalVerbs,
natureAdjectives,
natureNouns,
plantNouns,
plantVerbs ];
}
return key;
}
function writeHaiku(wordArray, ipv6) {
var octet, schemaResults, schema, nonWords, haiku;
octet = 'OCTET'; // String to place in schema to show word slots
schemaResults = getSchema(ipv6, octet);
schema = schemaResults[0];
nonWords = schemaResults[1];
/*
** Replace each instance of 'octet' in the schema with a word from
** the encoded word array
*/
for (var i = 0; i < wordArray.length; i++) {
for (var j = 0; j < schema.length; j++) {
if (schema[j] === octet) {
schema[j] = wordArray[i];
break;
}
}
}
/*
** Capitalize appropriate words
*/
schema = capitalizeHaiku(schema);
haiku = schema.join('');
return haiku;
}
function getSchema(ipv6, octet) {
var schema, newLine, period, space, nonWords;
schema = [];
newLine = '\n';
period = '.';
space = ' ';
nonWords = [newLine, period, space];
if (ipv6) {
schema = [octet,
octet,
'and',
octet,
octet,
newLine,
octet,
octet,
octet,
octet,
octet,
octet,
octet,
period,
newLine,
octet,
octet,
octet,
octet,
octet,
period,
newLine];
} else {
schema = ['The',
octet,
octet,
octet,
newLine,
octet,
'in the',
octet,
octet,
period,
newLine,
octet,
octet,
period,
newLine];
}
/*
** Add spaces before words except the first word
*/
for (var i = 1; i < schema.length; i++) {
var insertSpace = true;
/*
** If the next entry is a nonWord, don't add a space
*/
for (var j = 0; j < nonWords.length; j++) {
if (schema[i] === nonWords[j]) {
insertSpace = false;
}
}
/*
** If the previous entry is a newLine, don't add a space
*/
if (schema[i - 1] === newLine) {
insertSpace = false;
}
if (insertSpace) {
schema.splice(i, 0, space);
i = i + 1;
}
}
return [schema, nonWords];
}
function capitalizeHaiku(haikuArray) {
var period = '.';
/*
** Always capitalize the first word
*/
haikuArray[0] = capitalizeWord(haikuArray[0]);
for (var i = 1; i < haikuArray.length; i++) {
if (haikuArray[i] === period && i + 2 < haikuArray.length) {
/*
** If the current entry is a period then the next entry will be
** a newLine or a space, so check two positions ahead and
** capitalize that entry, so long as it's a word
*/
haikuArray[i + 2] = capitalizeWord(haikuArray[i + 2]);
}
}
return haikuArray;
}
function capitalizeWord(word) {
word = word.substring(0,1).toUpperCase() +
word.substring(1, word.length);
return word;
}
/*
** #############################
** Helper functions for decoding
** #############################
*/
function splitHaiku(haiku) {
var wordArray;
haiku = haiku.toLowerCase();
/*
** Replace newline characters with spaces
*/
haiku = haiku.replace(/\n/g, ' ');
/*
** Remove anything that's not a letter, a space or a dash
*/
haiku = haiku.replace(/[^a-z\ -]/g, '');
wordArray = haiku.split(' ');
/*
** Remove any blank entries
*/
for (var i = 0; i < wordArray.length; i++) {
if (wordArray[i] === '') {
wordArray.splice(i, 1);
}
}
return wordArray;
}
function haikuIsIpv6(wordArray) {
var ipv6, key, dict;
key = getKey(false);
dict = key[0];
ipv6 = true;
/*
** Compare each word in the haiku against each word in the first
** dictionary defined in the IPv4 key. If there's a match, the
** current haiku is IPv4. If not, IPv6.
*/
for (var i = 0; i < wordArray.length; i++) {
var currentWord = wordArray[i];
for (var j = 0; j < dict.length; j++) {
if (currentWord === dict[j]) {
ipv6 = false;
break;
}
}
if (ipv6 === false) {
break;
}
}
return ipv6;
}
/*
** Return an array of factors and remainders for each encoded
** octet-value
*/
function getFactors(wordArray, ipv6) {
var key, factorArray, wordArrayPosition;
key = getKey(ipv6);
factorArray = [];
wordArrayPosition = 0;
/*
** Get the first dictionary from the key. Check the first entry in
** the encoded word array to see if it's in that dictionary. If it
** is, store the dictionary offset and move onto the next dictionary
** and the next word in the encoded words array. If there isn't a
** match, keep the same dictionary but check the next word in the
** array. Keep going till we have an offset for each dictionary in
** the key.
*/
for (var i = 0; i < key.length; i++) {
var result, factor, newPosition;
result = [];
result = getFactorFromWord(key[i], key.length,
wordArray, wordArrayPosition);
factor = result[0];
newPosition = result[1];
wordArrayPosition = newPosition;
factorArray.push(factor);
}
return factorArray;
}
function getFactorFromWord(dict, maxLength, words, position) {
var factor = null;
for (var j = 0; j < dict.length; j++) {
var dictEntryLength, wordToCheck;
/*
** Get the number of words in the dictionary entry
*/
dictEntryLength = dict[j].split(' ').length;
/*
** build a string to compare against the dictionary entry
** by joining the appropriate number of wordArray entries
*/
wordToCheck =
words.slice(position, position + dictEntryLength);
wordToCheck = wordToCheck.join(' ');
if (dict[j] === wordToCheck) {
factor = j;
/*
** If the dictionary entry word count is greater than one,
** increment the position counter by the difference to
** avoid rechecking words we've already checkced
*/
position = position + (dictEntryLength - 1);
break;
}
}
position = position + 1;
if (factor === null) {
if (position >= maxLength) {
/*
** We've reached the entry of the haiku and still not matched
** all necessary dictionaries, so throw an error
*/
throw new Error('Decoding error: one or more dictionary words' +
'missing from input haiku');
} else {
/*
** Couldn't find the current word in the current dictionary,
** try the next word
*/
return getFactorFromWord(dict, maxLength, words, position);
}
} else {
/*
** Found the word - return the dictionary offset and the new
** word array position
*/
return [factor, position];
}
}
function getOctets(factorArray, ipv6) {
var octetArray, multiplier;
octetArray = [];
if (ipv6) {
multiplier = 256;
} else {
multiplier = 16;
}
for (var i = 0; i < factorArray.length; i = i + 2) {
var factor1, factor2, octet;
factor1 = factorArray[i];
factor2 = factorArray[i + 1];
octet = (factor1 * multiplier) + factor2;
if (ipv6) {
octet = octet.toString(16);
}
octetArray.push(octet);
}
return octetArray;
}
function getIpString(octetArray, ipv6) {
var ipString, separator;
ipString = '';
if (ipv6) {
separator = ':';
} else {
separator = '.';
}
for (var i = 0; i < octetArray.length; i++) {
if (i > 0) {
ipString += separator;
}
ipString += octetArray[i];
}
return ipString;
}
/*
** ############
** Dictionaries
** ############
*/
var adjectives, nouns, verbs, animalAdjectives, animalColors,
animalNouns, animalVerbs, natureAdjectives, natureNouns,
plantNouns, plantVerbs;
/*
** IPv4 dictionaries
*/
animalAdjectives = ['agile',
'bashful',
'clever',
'clumsy',
'drowsy',
'fearful',
'graceful',
'hungry',
'lonely',
'morose',
'placid',
'ruthless',
'silent',
'thoughtful',
'vapid',
'weary'];
animalColors = ['beige',
'black',
'blue',
'bright',
'bronze',
'brown',
'dark',
'drab',
'green',
'gold',
'grey',
'jade',
'pale',
'pink',
'red',
'white'];
animalNouns = ['ape',
'bear',
'crow',
'dove',
'frog',
'goat',
'hawk',
'lamb',
'mouse',
'newt',
'owl',
'pig',
'rat',
'snake',
'toad',
'wolf'];
animalVerbs = ['aches',
'basks',
'cries',
'dives',
'eats',
'fights',
'groans',
'hunts',
'jumps',
'lies',
'prowls',
'runs',
'sleeps',
'thrives',
'wakes',
'yawns'];
natureAdjectives = ['ancient',
'barren',
'blazing',
'crowded',
'distant',
'empty',
'foggy',
'fragrant',
'frozen',
'moonlit',
'peaceful',
'quiet',
'rugged',
'serene',
'sunlit',
'wind-swept'];
natureNouns = ['canyon',
'clearing',
'desert',
'foothills',
'forest',
'grasslands',
'jungle',
'meadow',
'mountains',
'prairie',
'river',
'rockpool',
'sand-dune',
'tundra',
'valley',
'wetlands'];
plantNouns = ['autumn colors',
'cherry blossoms',
'chrysanthemums',
'crabapple blooms',
'the dry palm fronds',
'fat horse chestnuts',
'forget-me-nots',
'jasmine petals',
'lotus flowers',
'ripe blackberries',
'the maple seeds',
'the pine needles',
'tiger lillies',
'water lillies',
'willow branches',
'yellowwood leaves'];
plantVerbs = ['blow',
'crunch',
'dance',
'drift',
'drop',
'fall',
'grow',
'pile',
'rest',
'roll',
'show',
'spin',
'stir',
'sway',
'turn',
'twist'];
/*
** IPv6 dictionaries
*/
adjectives = ['ace',
'apt',
'arched',
'ash',
'bad',
'bare',
'beige',
'big',
'black',
'bland',
'bleak',
'blond',
'blue',
'blunt',
'blush',
'bold',
'bone',
'both',
'bound',
'brash',
'brass',
'brave',
'brief',
'brisk',
'broad',
'bronze',
'brushed',
'burned',
'calm',
'ceil',
'chaste',
'cheap',
'chilled',
'clean',
'coarse',
'cold',
'cool',
'corn',
'crass',
'crazed',
'cream',
'crisp',
'crude',
'cruel',
'cursed',
'cute',
'daft',
'damp',
'dark',
'dead',
'deaf',
'dear',
'deep',
'dense',
'dim',
'drab',
'dry',
'dull',
'faint',
'fair',
'fake',
'false',
'famed',
'far',
'fast',
'fat',
'fierce',
'fine',
'firm',
'flat',
'flawed',
'fond',
'foul',
'frail',
'free',
'fresh',
'full',
'fun',
'glum',
'good',
'grave',
'gray',
'great',
'green',
'grey',
'grim',
'gruff',
'hard',
'harsh',
'high',
'hoarse',
'hot',
'huge',
'hurt',
'ill',
'jade',
'jet',
'jinxed',
'keen',
'kind',
'lame',
'lank',
'large',
'last',
'late',
'lean',
'lewd',
'light',
'limp',
'live',
'loath',
'lone',
'long',
'loose',
'lost',
'louche',
'loud',
'low',
'lush',
'mad',
'male',
'masked',
'mean',
'meek',
'mild',
'mint',
'moist',
'mute',
'near',
'neat',
'new',
'nice',
'nude',
'numb',
'odd',
'old',
'pained',
'pale',
'peach',
'pear',
'peeved',
'pink',
'piqued',
'plain',
'plum',
'plump',
'plush',
'poor',
'posed',
'posh',
'prim',
'prime',
'prompt',
'prone',
'proud',
'prune',
'puce',
'pure',
'quaint',
'quartz',
'quick',
'rare',
'raw',
'real',
'red',
'rich',
'ripe',
'rough',
'rude',
'rushed',
'rust',
'sad',
'safe',
'sage',
'sane',
'scorched',
'shaped',
'sharp',
'sheared',
'short',
'shrewd',
'shrill',
'shrunk',
'shy',
'sick',
'skilled',
'slain',
'slick',
'slight',
'slim',
'slow',
'small',
'smart',
'smooth',
'smug',
'snide',
'snug',
'soft',
'sore',
'sought',
'sour',
'spare',
'sparse',
'spent',
'spoilt',
'spry',
'squat',
'staid',
'stale',
'stark',
'staunch',
'steep',
'stiff',
'strange',
'straw',
'stretched',
'strict',
'striped',
'strong',
'suave',
'sure',
'svelte',
'swank',
'sweet',
'swift',
'tall',
'tame',
'tan',
'tart',
'taut',
'teal',
'terse',
'thick',
'thin',
'tight',
'tiny',
'tired',
'toothed',
'torn',
'tough',
'trim',
'trussed',
'twin',
'used',
'vague',
'vain',
'vast',
'veiled',
'vexed',
'vile',
'warm',
'weak',
'webbed',
'wrong',
'wry',
'young'];
nouns = ['ants',
'apes',
'asps',
'balls',
'barb',
'barbs',
'bass',
'bats',
'beads',
'beaks',
'bears',
'bees',
'bells',
'belts',
'birds',
'blades',
'blobs',
'blooms',
'boars',
'boats',
'bolts',
'books',
'bowls',
'boys',
'bream',
'brides',
'broods',
'brooms',
'brutes',
'bucks',
'bulbs',
'bulls',
'burls',
'cakes',
'calves',
'capes',
'cats',
'char',
'chests',
'choirs',
'clams',
'clans',
'clouds',
'clowns',
'cod',
'coins',
'colts',
'cones',
'cords',
'cows',
'crabs',
'cranes',
'crows',
'cults',
'czars',
'darts',
'dates',
'deer',
'dholes',
'dice',
'discs',
'does',
'dogs',
'doors',
'dopes',
'doves',
'drakes',
'dreams',
'drones',
'ducks',
'dunes',
'eels',
'eggs',
'elk',
'elks',
'elms',
'elves',
'ewes',
'eyes',
'faces',
'facts',
'fawns',
'feet',
'ferns',
'fish',
'fists',
'flames',
'fleas',
'flocks',
'flutes',
'foals',
'foes',
'fools',
'fowl',
'frogs',
'fruits',
'gangs',
'gar',
'geese',
'gems',
'germs',
'ghosts',
'gnomes',
'goats',
'grapes',
'grooms',
'grouse',
'grubs',
'guards',
'gulls',
'hands',
'hares',
'hawks',
'heads',
'hearts',
'hens',
'herbs',
'hills',
'hogs',
'holes',
'hordes',
'ide',
'jars',
'jays',
'kids',
'kings',
'kites',
'lads',
'lakes',
'lambs',
'larks',
'lice',
'lights',
'limbs',
'looms',
'loons',
'mares',
'masks',
'mice',
'mimes',
'minks',
'mists',
'mites',
'mobs',
'molds',
'moles',
'moons',
'moths',
'newts',
'nymphs',
'orbs',
'orcs',
'owls',
'pearls',
'pears',
'peas',
'perch',
'pigs',
'pikes',
'pines',
'plains',
'plants',
'plums',
'pools',
'prawns',
'prunes',
'pugs',
'punks',
'quail',
'quails',
'queens',
'quills',
'rafts',
'rains',
'rams',
'rats',
'rays',
'ribs',
'rocks',
'rooks',
'ruffs',
'runes',
'sands',
'seals',
'seas',
'seeds',
'serfs',
'shards',
'sharks',
'sheep',
'shells',
'ships',
'shoals',
'shrews',
'shrimp',
'skate',
'skies',
'skunks',
'sloths',
'slugs',
'smew',
'smiles',
'snails',
'snakes',
'snipes',
'sole',
'songs',
'spades',
'sprats',
'sprouts',
'squabs',
'squads',
'squares',
'squid',
'stars',
'stoats',
'stones',
'storks',
'strays',
'suns',
'swans',
'swarms',
'swells',
'swifts',
'tars',
'teams',
'teeth',
'terns',
'thorns',
'threads',
'thrones',
'ticks',
'toads',
'tools',
'trees',
'tribes',
'trolls',
'trout',
'tunes',
'tusks',
'veins',
'verbs',
'vines',
'voles',
'wasps',
'waves',
'wells',
'whales',
'whelks',
'whiffs',
'winds',
'wolves',
'worms',
'wraiths',
'wrens',
'yaks'];
verbs = ['aid',
'arm',
'awe',
'axe',
'bag',
'bait',
'bare',
'bash',
'bathe',
'beat',
'bid',
'bilk',
'blame',
'bleach',
'bleed',
'bless',
'bluff',
'blur',
'boast',
'boost',
'boot',
'bore',
'botch',
'breed',
'brew',
'bribe',
'brief',
'brine',
'broil',
'browse',
'bruise',
'build',
'burn',
'burst',
'call',
'calm',
'carve',
'chafe',
'chant',
'charge',
'chart',
'cheat',
'check',
'cheer',
'chill',
'choke',
'chomp',
'choose',
'churn',
'cite',
'clamp',
'clap',
'clasp',
'claw',
'clean',
'cleanse',
'clip',
'cloak',
'clone',
'clutch',
'coax',
'crack',
'crave',
'crunch',
'cry',
'cull',
'cure',
'curse',
'cuss',
'dare',
'daze',
'dent',
'dig',
'ding',
'doubt',
'dowse',
'drag',
'drain',
'drape',
'draw',
'dread',
'dredge',
'drill',
'drink',
'drip',
'drive',
'drop',
'drown',
'dry',
'dump',
'eat',
'etch',
'face',
'fail',
'fault',
'fear',
'feed',
'feel',
'fetch',
'fight',
'find',
'fix',
'flap',
'flay',
'flee',
'fling',
'flip',
'float',
'foil',
'forge',
'free',
'freeze',
'frisk',
'gain',
'glimpse',
'gnaw',
'goad',
'gouge',
'grab',
'grasp',
'graze',
'grieve',
'grip',
'groom',
'guard',
'guards',
'guide',
'gulp',
'gush',
'halt',
'harm',
'hate',
'haul',
'haunt',
'have',
'heal',
'hear',
'help',
'herd',
'hex',
'hire',
'hit',
'hoist',
'hound',
'hug',
'hurl',
'irk',
'jab',
'jeer',
'join',
'jolt',
'keep',
'kick',
'kill',
'kiss',
'lash',
'leash',
'leave',
'lift',
'like',
'love',
'lug',
'lure',
'maim',
'make',
'mask',
'meet',
'melt',
'mend',
'miss',
'mould',
'move',
'nab',
'name',
'need',
'oust',
'paint',
'paw',
'pay',
'peck',
'peeve',
'pelt',
'please',
'pluck',
'poach',
'poll',
'praise',
'prick',
'print',
'probe',
'prod',
'prompt',
'punch',
'quash',
'quell',
'quote',
'raid',
'raise',
'raze',
'ride',
'roast',
'rouse',
'rule',
'scald',
'scalp',
'scar',
'scathe',
'score',
'scorn',
'scour',
'scuff',
'sear',
'see',
'seek',
'seize',
'send',
'sense',
'serve',
'shake',
'shear',
'shift',
'shoot',
'shun',
'slap',
'slay',
'slice',
'smack',
'smash',
'smell',
'smite',
'snare',
'snatch',
'sniff',
'snub',
'soak',
'spare',
'splash',
'split',
'spook',
'spray',
'squash',
'squeeze',
'stab',
'stain',
'starve',
'steal',
'steer',
'sting',
'strike',
'stun',
'tag',
'tame',
'taste',
'taunt',
'teach',
'tend'];
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
module.exports = publicMethods;
} else {
return publicMethods;
}
})();
================================================
FILE: package.json
================================================
{
"name": "hipku",
"version": "2.0.0",
"description": "Encode any IP address as a haiku",
"main": "index.js",
"devDependencies": {
"jasmine-node": ">=1.14.5"
},
"scripts": {
"test": "jasmine-node test/spec"
},
"repository": {
"type": "git",
"url": "https://github.com/gabemart/hipku.git"
},
"keywords": [
"poetry",
"ipv4",
"ipv6",
"haiku"
],
"author": {
"name": "Gabriel Martin"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/gabemart/hipku/issues"
},
"homepage": "http://gabrielmartin.net/projects/hipku"
}
================================================
FILE: test/spec/allVersions.spec.js
================================================
/*
** Test that when you take an IP address, encode it, and then decode it
** again, it matches the original address. These tests are applicable to
** all versions of Hipku, regardless of changes to the dictionaries or
** schema.
*/
var Hipku = require('../../index.js');
describe("All versions of Hipku", function() {
it("should symmetrically encode and decode IPv4 addresses", function() {
expect(
Hipku.decode(Hipku.encode('0.0.0.0'))
).toBe('0.0.0.0');
expect(
Hipku.decode(Hipku.encode('127.0.0.1'))
).toBe('127.0.0.1');
expect(
Hipku.decode(Hipku.encode('82.158.98.2'))
).toBe('82.158.98.2');
expect(
Hipku.decode(Hipku.encode('255.255.255.255'))
).toBe('255.255.255.255');
});
it("should symmetrically encode and decode IPv6 addresses", function() {
expect(
Hipku.decode(Hipku.encode('0:0:0:0:0:0:0:0'))
).toBe('0:0:0:0:0:0:0:0');
expect(
Hipku.decode(Hipku.encode('2c8f:27aa:61fd:56ec:7ebe:d03a:1f50:475f'))
).toBe('2c8f:27aa:61fd:56ec:7ebe:d03a:1f50:475f');
expect(
Hipku.decode(Hipku.encode('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'))
).toBe('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff');
});
it("should correctly expand the abbreviated IPv6 format", function() {
var fullAddress = '0:0:0:0:0:0:0:0';
expect(
Hipku.decode(Hipku.encode('::0'))
).toBe(fullAddress);
expect(
Hipku.decode(Hipku.encode('0::'))
).toBe(fullAddress);
expect(
Hipku.decode(Hipku.encode('0::0'))
).toBe(fullAddress);
expect(
Hipku.decode(Hipku.encode('0:0::0:0'))
).toBe(fullAddress);
});
});
================================================
FILE: test/spec/currentVersion.spec.js
================================================
/*
** Test that a series of encoded test IPs match haiku for the current
** set of dictionaries and schema, and that a series of decoded test
** haiku match IPs for the current dictionaries and schema. These tests
** must be updated whenever the dictionaries or schema are changed.
*/
var Hipku = require('../../index.js');
describe("The current version of Hipku", function() {
var Ipv4HipkuIpPairs, Ipv6HipkuIpPairs;
beforeEach(function() {
Ipv4HipkuIpPairs = [
['0.0.0.0', 'The agile beige ape\naches in the ancient canyon.\nAutumn colors blow.\n'],
['127.0.0.1', 'The hungry white ape\naches in the ancient canyon.\nAutumn colors crunch.\n'],
['82.158.98.2', 'The fearful blue newt\nwakes in the foggy desert.\nAutumn colors dance.\n'],
['255.255.255.255', 'The weary white wolf\nyawns in the wind-swept wetlands.\nYellowwood leaves twist.\n']
];
Ipv6HipkuIpPairs = [
['0:0:0:0:0:0:0:0',
'Ace ants and ace ants\naid ace ace ace ace ace ants.\nAce ants aid ace ants.\n'],
['2c8f:27aa:61fd:56ec:7ebe:d03a:1f50:475f',
'Cursed mobs and crazed queens\nfeel wrong gruff tired moist slow sprats.\nFaint bulls dread fond fruits.\n'],
['ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
'Young yaks and young yaks\ntend young young young young young yaks.\nYoung yaks tend young yaks.\n']
];
});
afterEach(function() {
Ipv4HipkuIpPairs = null;
Ipv6HipkuIpPairs = null;
});
it("should correctly encode a series of test IPv4 addresses", function() {
for (var i = 0; i < Ipv4HipkuIpPairs.length; i++) {
expect(
Hipku.encode(Ipv4HipkuIpPairs[i][0])
).toBe(Ipv4HipkuIpPairs[i][1]);
}
});
it("should correctly decode a series of test IPv4 hipku", function() {
for (var i = 0; i < Ipv4HipkuIpPairs.length; i++) {
expect(
Hipku.decode(Ipv4HipkuIpPairs[i][1])
).toBe(Ipv4HipkuIpPairs[i][0]);
}
});
it("should correctly encode a series of test IPv6 addresses", function() {
for (var i = 0; i < Ipv6HipkuIpPairs.length; i++) {
expect(
Hipku.encode(Ipv6HipkuIpPairs[i][0])
).toBe(Ipv6HipkuIpPairs[i][1]);
}
});
it("should correctly decode a series of test IPv6 hipku", function() {
for (var i = 0; i < Ipv6HipkuIpPairs.length; i++) {
expect(
Hipku.decode(Ipv6HipkuIpPairs[i][1])
).toBe(Ipv6HipkuIpPairs[i][0]);
}
});
});
gitextract_pxxfoasq/
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── index.js
├── package.json
└── test/
└── spec/
├── allVersions.spec.js
└── currentVersion.spec.js
SYMBOL INDEX (16 symbols across 1 files)
FILE: index.js
function ipIsIpv6 (line 64) | function ipIsIpv6(ip) {
function splitIp (line 73) | function splitIp(ip, ipv6) {
function padOctets (line 125) | function padOctets(octetArray, numMissingOctets) {
function factorOctets (line 161) | function factorOctets(octetArray, ipv6) {
function encodeWords (line 188) | function encodeWords(factorArray, ipv6) {
function getKey (line 209) | function getKey(ipv6) {
function writeHaiku (line 243) | function writeHaiku(wordArray, ipv6) {
function getSchema (line 273) | function getSchema(ipv6, octet) {
function capitalizeHaiku (line 354) | function capitalizeHaiku(haikuArray) {
function capitalizeWord (line 377) | function capitalizeWord(word) {
function splitHaiku (line 390) | function splitHaiku(haiku) {
function haikuIsIpv6 (line 418) | function haikuIsIpv6(wordArray) {
function getFactors (line 452) | function getFactors(wordArray, ipv6) {
function getFactorFromWord (line 484) | function getFactorFromWord(dict, maxLength, words, position) {
function getOctets (line 542) | function getOctets(factorArray, ipv6) {
function getIpString (line 569) | function getIpString(octetArray, ipv6) {
Condensed preview — 8 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (32K chars).
[
{
"path": ".gitignore",
"chars": 23,
"preview": "TODO.txt\nnode_modules/\n"
},
{
"path": ".npmignore",
"chars": 0,
"preview": ""
},
{
"path": "LICENSE",
"chars": 1082,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2014 Gabriel Martin\n\nPermission is hereby granted, free of charge, to any person ob"
},
{
"path": "README.md",
"chars": 1151,
"preview": "# Hipku\n\nA tiny javascript library to encode IPv6 and IPv4 addresses as haiku.\n\nFor full documentation and a working dem"
},
{
"path": "index.js",
"chars": 22751,
"preview": "/*\n** Hipku version 0.0.2\n** Copyright (c) Gabriel Martin 2014\n** All rights reserved\n** Available under the MIT license"
},
{
"path": "package.json",
"chars": 595,
"preview": "{\n \"name\": \"hipku\",\n \"version\": \"2.0.0\",\n \"description\": \"Encode any IP address as a haiku\",\n \"main\": \"index.js\",\n "
},
{
"path": "test/spec/allVersions.spec.js",
"chars": 1714,
"preview": "/*\n** Test that when you take an IP address, encode it, and then decode it\n** again, it matches the original address. Th"
},
{
"path": "test/spec/currentVersion.spec.js",
"chars": 2482,
"preview": "/*\n** Test that a series of encoded test IPs match haiku for the current \n** set of dictionaries and schema, and that a "
}
]
About this extraction
This page contains the full source code of the gabemart/hipku GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 8 files (29.1 KB), approximately 10.0k tokens, and a symbol index with 16 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.