Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

sweatmap

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sweatmap - npm Package Compare versions

Comparing version 0.0.4 to 0.0.5

browser/sweatmap-0.0.5.min.js

119

node/sweatmap.js
'use strict';
const uniq = require('lodash.uniq');
const uniq = require('lodash/uniqWith');
const isEqual = require('lodash/isEqual');

@@ -8,3 +9,3 @@ const SweatMap = class SweatMap {

obj = typeof obj == 'object' ? obj : {};
//Adhere to CSS class/id rules -> https://www.w3.org/TR/CSS2/syndata.html#characters

@@ -16,6 +17,6 @@ //Does not yet work with escaped characters or ISO 10646 characters as a numeric code

this.fmap = new Map();
//Map containing obfuscated string to original string values
this.rmap = new Map();
//Available characters keyed by number of bytes

@@ -135,3 +136,3 @@ this.characters = {};

}, obj.additional_ranges);
//Add existing strings to map

@@ -151,3 +152,3 @@ if(typeof obj.existing_strings == 'object') {

return;
for(let i = parseInt(Ranges[CR].start, 16); i <= parseInt(Ranges[CR].end, 16); i++) {

@@ -167,3 +168,3 @@ try {

});
//Removes duplicate chars in the array then freeze to ensure nothing is changed

@@ -174,6 +175,6 @@ Object.keys(this.characters).forEach(C => {

});
Object.freeze(this.characters);
}
bytes(str) {

@@ -183,3 +184,3 @@ //Determine how many bytes are in a given utf8 string -> https://gist.github.com/mathiasbynens/1010324

}
cssSafeString(str) {

@@ -190,6 +191,44 @@ //https://www.w3.org/TR/CSS2/syndata.html#characters

return false;
return true;
}
size() {
return this.fmap.size && this.rmap.size;
}
generatePatternForBytes(bytes) {
// Find all the different possible combinations of sums
const calculateSumCombinations = (n) => {
const possibleSums = [];
let subset = [];
// Our subset sum function for finding possible sums combinations for our target value
const subsetSum = (subset, target, partial = []) => {
let s = partial.reduce((a, b) => a + b, 0);
if (s === target) possibleSums.push(partial);
else if (s >= target) return;
subset.forEach(num => subsetSum(subset.slice(1), target, partial.concat(num)));
};
// Create our subset
for (let i = 1; i <= n; i++) {
// Adding max duplicates of each number to simplify the logic
// It also has the benefit of not needing to calculate permutations separately once we remove duplicates
subset = subset.concat(new Array(n).fill(i));
}
subsetSum(subset, n);
return possibleSums;
};
return uniq(calculateSumCombinations(bytes), isEqual)
.map(pattern => pattern
.map(val => this.characters[`${val}`])
);
}
set(key) {

@@ -199,3 +238,3 @@ //If it's already been done, don't do it again!

return this.fmap.get(key);
//If the key is not a string, throw an error

@@ -205,24 +244,2 @@ if(typeof key != 'string' || key === '')

const getPatterns = () => {
//Hard Coded For Now
if(bytes === 1) {
return [
[this.characters['1']] //A
];
} else if(bytes == 2) {
return [
[this.characters['1'], this.characters['1']], //AA
[this.characters['2']] //B
];
} else if(bytes == 3) {
return [
[this.characters['1'], this.characters['1'], this.characters['1']], //AAA
[this.characters['2'], this.characters['1']], //BA
[this.characters['1'], this.characters['2']], //AB
[this.characters['3']] //C
];
}
//
};
const isGoodValue = value => {

@@ -234,3 +251,3 @@ if(this.cssSafe)

};
var bytes = 0, //Determines what patterns to try

@@ -244,4 +261,4 @@ value; //The obfuscated UTF-8 String

//Get all possible patterns
let patterns = getPatterns();
let patterns = this.generatePatternForBytes(bytes);
//Which pattern are we are currently trying

@@ -253,6 +270,6 @@ let patternsCounter = 0;

let currentPattern = patterns[patternsCounter];
//Array of counters, one for each charlist
let currentPatternCounters = currentPattern.map(() => 0);
//Last possible match

@@ -270,10 +287,10 @@ let lastMatch = currentPattern.map(charlist => charlist[charlist.length-1]).join('');

});
//Increment Counters
for(let i = 0, ln = currentPatternCounters.length; i < ln; i++) {
currentPatternCounters[i]++;
//If the current counter is less than or equal to the total number of chars in this charlist, you don't need to increment anymore
if(currentPatternCounters[i] <= currentPattern[i].length) {
//If it's equal and there are more charlists

@@ -284,3 +301,3 @@ if(currentPatternCounters[i] == currentPattern[i].length && i < ln-1) {

}
break;

@@ -302,6 +319,6 @@ }

}
delete(key) {
const value = this.fmap.get(key);
if(value !== undefined) {

@@ -312,3 +329,3 @@ this.fmap.delete(key);

}
clear() {

@@ -318,15 +335,15 @@ this.fmap.clear();

}
entries() {
return this.fmap.entries();
}
get(key) {
return this.fmap.get(key);
}
get_obfuscated(value) {
return this.rmap.get(value);
}
has(key) {

@@ -338,3 +355,3 @@ if(!key)

}
has_obfuscated(value) {

@@ -341,0 +358,0 @@ if(!value)

{
"name": "sweatmap",
"description": "SweatMap takes in a series of UTF-8 strings and maps them to UTF-8 strings that are as small as possible while still being unique.",
"version": "0.0.4",
"version": "0.0.5",
"author": {

@@ -34,12 +34,12 @@ "name": "Benjamin Solum",

"dependencies": {
"lodash.uniq": "^4.2.0"
"lodash": "^4.17.4"
},
"devDependencies": {
"babel-core": "^6.7.4",
"babel-loader": "^6.2.4",
"babel-preset-es2015": "^6.6.0",
"babel-loader": "^6.2.10",
"babel-preset-es2015": "^6.18.0",
"eslint": "^2.5.3",
"mocha": "^2.4.5",
"webpack": "^1.12.14"
"webpack": "^1.14.0"
}
}

@@ -8,5 +8,26 @@ #SweatMap

##Installation
Coming soon.
`npm install sweatmap --save`
##How to use
Coming soon, but source is pretty simple to read.
*SweatMap uses a few ES6 features that may not be present in your Node/Browser depending on the version.*
These include: `Array.fill`, `Object.assign`, `Object.freeze`, and `Object.keys`
* **Constructor(obj):**
*Takes in an object with up to three optional properties:*
* *cssSafe [default `false`]:* `true` disallows characters that aren't safe for [CSS Identifiers](https://www.w3.org/TR/CSS2/syndata.html#characters).
* *additional_ranges [[`object`](https://github.com/soluml/SweatMap/blob/master/node/sweatmap.js#L27)]:* An object where the key is a "range name" and the value is an object with a start character point and an end character point. You can set null to either start or end to remove a character range.
* *existing_strings [default `{}`]:* Pass in an object of strings that you don't want changed. Key is the original name, value is the name that should be used.
* **bytes(string):** Returns a byte count of the string passed in.
* **size():** Returns number of entries in the map.
* **cssSafeString(string):** Determines if the string is a safe [CSS Identifier](https://www.w3.org/TR/CSS2/syndata.html#characters).
* **set(string):** Returns an obfuscated UTF-8 string that's unique to all strings in the map.
* **delete(key):** Removes the string from the map.
* **clear():** Empties the map.
* **clear():** Empties the map.
* **entries():** Returns a new Iterator object that contains the [key, value] pairs for each element in the Map object in insertion order.
* **get(key):** Returns the value for a given key.
* **get_obfuscated(value):** Returns the key for a given value.
* **has(key):** Returns true/false if a key exists in the map.
* **has_obfuscated(value):** Returns true/false if a value exists in the map.

@@ -11,3 +11,3 @@ 'use strict';

var myMap = new SweatMap();
assert.equal(myMap.characters['1'].length, 96);

@@ -17,3 +17,3 @@ assert.equal(myMap.characters['2'].length, 1776);

});
it('Can pass in existing UTF-8 String key/values:', function() {

@@ -35,3 +35,3 @@ var myMap = new SweatMap({

});
it('Can pass in adjusted character ranges:', function() {

@@ -51,3 +51,3 @@ var myMap = new SweatMap({

});
it('Character ranges are frozen:', function() {

@@ -61,3 +61,3 @@ var myMap = new SweatMap();

});
it('No default entries:', function() {

@@ -69,3 +69,3 @@ var myMap = new SweatMap();

});
it('Can set CSS Safe Mode:', function() {

@@ -77,5 +77,5 @@ var myMap = new SweatMap({ cssSafe: true });

});
describe('bytes(str)', function () {
it('Returns bytes for a given string:', function () {

@@ -91,7 +91,23 @@ var myMap = new SweatMap();

});
});
describe('size(str)', function () {
it('Returns size of map:', function () {
var myMap = new SweatMap();
assert.equal(myMap.size(), 0);
myMap.set('aA');
myMap.set('×');
myMap.set('×ø×ø!');
myMap.set('☃');
myMap.set('�bb☃');
assert.equal(myMap.size(), 5);
});
});
describe('cssSafeString(str)', function () {
it('Determines if a string is a valid css identifier (e.g. class/id):', function () {

@@ -110,9 +126,60 @@ var myMap = new SweatMap();

});
});
describe('generatePatternForBytes(bytes)', function () {
var myMap;
var patternCountTest = function (bytes) {
var expectedPatterns = Math.pow(2, bytes - 1);
var patterns = myMap.generatePatternForBytes(bytes);
var patternCount = 0;
for (var i = 0; i < expectedPatterns; i++) {
try {
if (patterns[i].length > 0) {
patternCount++;
}
} catch (err) {
break;
}
}
assert.equal(patternCount, expectedPatterns);
};
beforeEach(function() {
myMap = new SweatMap({
"additional_ranges": {
"A-Z": { start: '41', end: '5A' }, //Add A-Z
"a-z": { start: '61', end: '7A' }, //Add a-z
"Basic Latin": { end: null } //Removes Basic Latin
}
});
});
it('Should generate proper number of patterns for 1 bytes', function () {
patternCountTest(1);
});
it('Should generate proper number of patterns for 2 bytes', function () {
patternCountTest(2);
});
it('Should generate proper number of patterns for 3 bytes', function () {
patternCountTest(3);
});
it('Should generate proper number of patterns for 4 bytes', function () {
patternCountTest(4);
});
it('Should generate proper number of patterns for 5 bytes', function () {
patternCountTest(5);
});
});
describe('set(key)', function () {
var myMap;
beforeEach(function() {

@@ -134,3 +201,3 @@ myMap = new SweatMap({

});
it('Returns an error if the key is not a string:', function () {

@@ -144,13 +211,13 @@ assert.throws(() => { myMap.set({}); }, Error, '{} is not a string');

});
it('Returns an error if the key is an empty string:', function () {
assert.throws(() => { myMap.set(''); }, Error, '"" is an empty string');
});
it('Obfuscates the given keys correctly:', function () {
//LONG Timeout -> 1min
this.timeout(60000);
var i, str;
assert.equal(myMap.characters['1'].length, 52);

@@ -162,3 +229,3 @@ assert.equal(myMap.characters['2'].length, 1776);

str = myMap.set('string'+ i);
if(i < 52) { //(52)[A] == 52

@@ -173,10 +240,10 @@ assert.equal(myMap.bytes(str), 1);

});
it('Obfuscates the given keys correctly (CSS Safe):', function () {
//LONG Timeout -> 1min
this.timeout(60000);
var i, str, myOtherMap = new SweatMap({ cssSafe: true });
assert.equal(myOtherMap.characters['1'].length, 96);

@@ -186,6 +253,6 @@ assert.equal(myOtherMap.characters['2'].length, 1776);

assert.equal(myOtherMap.cssSafe, true);
for(i = 0; i < 5300; i++) {
str = myOtherMap.set('string'+ i);
if(i < 53) { // a-z(26) + A-Z(26) + _(1)

@@ -202,11 +269,11 @@ assert.equal(myMap.bytes(str), 1);

});
describe('delete(key)', function () {
it('Deletes values from both fmap and rmap for a given key:', function () {
var myMap = new SweatMap();
var astr = myMap.set('A-String');
var bstr = myMap.set('B-String');
assert.equal(myMap.fmap.has('A-String'), true);

@@ -216,3 +283,3 @@ assert.equal(myMap.fmap.has('B-String'), true);

assert.equal(myMap.rmap.has(bstr), true);
myMap.delete('B-String');

@@ -223,3 +290,3 @@ assert.equal(myMap.fmap.has('A-String'), true);

assert.equal(myMap.rmap.has(bstr), false);
myMap.delete('A-String');

@@ -231,13 +298,13 @@ assert.equal(myMap.fmap.has('A-String'), false);

});
});
describe('clear()', function () {
it('Clears values from both fmap and rmap:', function () {
var myMap = new SweatMap();
var astr = myMap.set('A-String');
var bstr = myMap.set('B-String');
assert.equal(myMap.fmap.has('A-String'), true);

@@ -247,3 +314,3 @@ assert.equal(myMap.fmap.has('B-String'), true);

assert.equal(myMap.rmap.has(bstr), true);
myMap.clear();

@@ -255,10 +322,10 @@ assert.equal(myMap.fmap.has('A-String'), false);

});
});
describe('entries()', function () {
it('Returns a new Iterator object that contains an array of [key, value] for each element in the Map object in insertion order:', function () {
var myMap = new SweatMap();
myMap.set('A-String');

@@ -269,58 +336,58 @@ myMap.set('B-String');

});
});
describe('get(key)', function () {
it('Get values from the map:', function () {
var myMap = new SweatMap();
var astr = myMap.set('A-String');
assert.equal(myMap.get('A-String'), astr);
assert.equal(myMap.get('A-String'), myMap.fmap.get('A-String'));
});
});
describe('get_obfuscated(value)', function () {
it('Get keys from the map:', function () {
var myMap = new SweatMap();
var astr = myMap.set('A-String');
assert.equal(myMap.get_obfuscated(astr), 'A-String');
assert.equal(myMap.get_obfuscated(astr), myMap.rmap.get(astr));
});
});
describe('has(key)', function () {
it('Can see if it has a key in the map:', function () {
var myMap = new SweatMap();
myMap.set('A-String');
assert.equal(myMap.has('A-String'), true);
myMap.delete('A-String');
assert.equal(myMap.has('A-String'), false);
});
});
describe('has_obfuscated(value)', function () {
it('Can see if it has a value in the map:', function () {
var myMap = new SweatMap();
var astr = myMap.set('A-String');
assert.equal(myMap.has_obfuscated(astr), true);
myMap.delete('A-String');
assert.equal(myMap.has(astr), false);
});
});
});
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc