Skip to content

Commit 8fbd9e7

Browse files
committed
first
0 parents  commit 8fbd9e7

File tree

5 files changed

+202
-0
lines changed

5 files changed

+202
-0
lines changed

.eslintrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": ["standard"]
3+
}

index.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
var Transform = require('stream').Transform
2+
var inherits = require('inherits')
3+
var StringDecoder = require('string_decoder').StringDecoder
4+
module.exports = CipherBase
5+
inherits(CipherBase, Transform)
6+
function CipherBase (hashMode) {
7+
Transform.call(this)
8+
this.hashMode = typeof hashMode === 'string';
9+
if (this.hashMode) {
10+
this[hashMode] = this._finalOrDigest
11+
} else {
12+
this.final = this._finalOrDigest
13+
}
14+
this._decoder = null
15+
this._encoding = null
16+
}
17+
CipherBase.prototype.update = function (data, inputEnc, outputEnc) {
18+
if (typeof data === 'string') {
19+
data = new Buffer(data, inputEnc)
20+
}
21+
var outData = this._update(data)
22+
if (this.hashMode) {
23+
return this
24+
}
25+
if (outputEnc) {
26+
outData = this._toString(outData, outputEnc)
27+
}
28+
return outData
29+
}
30+
CipherBase.prototype._transform = function (data, _, next) {
31+
var err
32+
try {
33+
this.push(this._update(data))
34+
} catch (e) {
35+
err = e
36+
} finally {
37+
next(err)
38+
}
39+
}
40+
CipherBase.prototype._flush = function (done) {
41+
var err
42+
try {
43+
this.push(this._final())
44+
} catch (e) {
45+
err = e
46+
} finally {
47+
done(err)
48+
}
49+
}
50+
CipherBase.prototype._finalOrDigest = function (outputEnc) {
51+
var outData = this._final() || new Buffer('')
52+
if (outputEnc) {
53+
outData = this._toString(outData, outputEnc, true)
54+
}
55+
return outData
56+
}
57+
58+
CipherBase.prototype._toString = function (value, enc, final) {
59+
if (!this._decoder) {
60+
this._decoder = new StringDecoder(enc)
61+
this._encoding = enc
62+
}
63+
if (this._encoding !== enc) {
64+
throw new Error('can\'t switch encodings')
65+
}
66+
var out = this._decoder.write(value)
67+
if (final) {
68+
out += this._decoder.end()
69+
}
70+
return out
71+
}

package.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "cipher-base",
3+
"version": "1.0.0",
4+
"description": "abstract base class for crypto-streams",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "node test.js | tspec"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/crypto-browserify/cipher-base.git"
12+
},
13+
"keywords": [
14+
"cipher",
15+
"stream"
16+
],
17+
"author": "Calvin Metcalf <calvin.metcalf@gmail.com>",
18+
"license": "MIT",
19+
"bugs": {
20+
"url": "https://github.com/crypto-browserify/cipher-base/issues"
21+
},
22+
"homepage": "https://github.com/crypto-browserify/cipher-base#readme",
23+
"dependencies": {
24+
"inherits": "^2.0.1"
25+
},
26+
"devDependencies": {
27+
"tap-spec": "^4.1.0",
28+
"tape": "^4.2.0"
29+
}
30+
}

readme.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
cipher-base
2+
===
3+
4+
Abstract base class to inherit from if you want to create streams implementing
5+
the same api as node crypto streams.
6+
7+
Requires you to implement 2 methods `_final` and `_update`. `_final` takes a
8+
buffer and should return a buffer, `_final` takes no arguments and should return
9+
a buffer.
10+
11+
12+
The constructor takes one argument and that is a string which if present switches
13+
it into hash mode, i.e. the object you get from crypto.createHash or
14+
crypto.createSign, this switches the name of the final method to be the string
15+
you passed instead of `final` and returns `this` from update.

test.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
var test = require('tape')
2+
var CipherBase = require('./')
3+
var inherits = require('inherits')
4+
5+
test('basic version', function (t) {
6+
inherits(Cipher, CipherBase)
7+
function Cipher () {
8+
CipherBase.call(this)
9+
}
10+
Cipher.prototype._update = function (input) {
11+
t.ok(Buffer.isBuffer(input))
12+
return input
13+
}
14+
Cipher.prototype._final = function () {
15+
// noop
16+
}
17+
var cipher = new Cipher()
18+
var utf8 = 'abc123abcd'
19+
var update = cipher.update(utf8, 'utf8', 'base64') + cipher.final('base64')
20+
var string = (new Buffer(update, 'base64')).toString()
21+
t.equals(utf8, string)
22+
t.end()
23+
})
24+
test('hash mode', function (t) {
25+
inherits(Cipher, CipherBase)
26+
function Cipher () {
27+
CipherBase.call(this, 'finalName')
28+
this._cache = []
29+
}
30+
Cipher.prototype._update = function (input) {
31+
t.ok(Buffer.isBuffer(input))
32+
this._cache.push(input)
33+
}
34+
Cipher.prototype._final = function () {
35+
return Buffer.concat(this._cache)
36+
}
37+
var cipher = new Cipher()
38+
var utf8 = 'abc123abcd'
39+
var update = cipher.update(utf8, 'utf8').finalName('base64')
40+
var string = (new Buffer(update, 'base64')).toString()
41+
42+
t.equals(utf8, string)
43+
t.end()
44+
})
45+
test('encodings', function (t) {
46+
inherits(Cipher, CipherBase)
47+
function Cipher () {
48+
CipherBase.call(this)
49+
}
50+
Cipher.prototype._update = function (input) {
51+
return input
52+
}
53+
Cipher.prototype._final = function () {
54+
// noop
55+
}
56+
t.test('mix and match encoding', function (t) {
57+
t.plan(2)
58+
59+
var cipher = new Cipher()
60+
cipher.update('foo', 'utf8', 'utf8')
61+
t.throws(function () {
62+
cipher.update('foo', 'utf8', 'base64')
63+
})
64+
cipher = new Cipher()
65+
cipher.update('foo', 'utf8', 'base64')
66+
t.doesNotThrow(function () {
67+
cipher.update('foo', 'utf8')
68+
cipher.final('base64')
69+
})
70+
})
71+
t.test('handle long uft8 plaintexts', function (t) {
72+
t.plan(1)
73+
var txt = 'ふっかつ あきる すぶり はやい つける まゆげ たんさん みんぞく ねほりはほり せまい たいまつばな ひはん'
74+
75+
var cipher = new Cipher()
76+
var decipher = new Cipher()
77+
var enc = decipher.update(cipher.update(txt, 'utf8', 'base64'), 'base64', 'utf8')
78+
enc += decipher.update(cipher.final('base64'), 'base64', 'utf8')
79+
enc += decipher.final('utf8')
80+
81+
t.equals(txt, enc)
82+
})
83+
})

0 commit comments

Comments
 (0)