Skip to content

Commit fb49355

Browse files
author
Benjamin Pasero
committed
debt - use crypto.digest for SHA1 over custom solution
1 parent b79058a commit fb49355

18 files changed

Lines changed: 143 additions & 401 deletions

File tree

src/vs/base/common/hash.ts

Lines changed: 0 additions & 249 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { isString } from 'vs/base/common/types';
7-
import { toUint8ArrayBuffer } from 'vs/base/common/uint';
8-
96
/**
107
* Return a hash value for an object.
118
*/
@@ -73,249 +70,3 @@ export class Hasher {
7370
return this._value;
7471
}
7572
}
76-
77-
//#region SHA1
78-
79-
export function computeSHA1Hash(value: string): string {
80-
const data = toUint8ArrayBuffer(value);
81-
const hash = new SHA1();
82-
83-
if (data.byteLength) {
84-
hash.update(data);
85-
}
86-
87-
return hash.digest();
88-
}
89-
90-
class SHA1 {
91-
92-
// Reference: http://en.wikipedia.org/wiki/SHA-1
93-
94-
private static BLOCK_SIZE = 64; // 512 / 8
95-
96-
private length: number;
97-
private buffer: Uint8Array | null;
98-
private bufferDV: DataView | null;
99-
private bufferLength: number;
100-
101-
private bigBlock32: DataView;
102-
private h0 = 0x67452301;
103-
private h1 = 0xEFCDAB89;
104-
private h2 = 0x98BADCFE;
105-
private h3 = 0x10325476;
106-
private h4 = 0xC3D2E1F0;
107-
108-
static digest(data: string): string;
109-
static digest(data: Uint8Array): string;
110-
static digest(data: ArrayBuffer): string;
111-
static digest(data: DataView): string;
112-
static digest(data: any): string {
113-
let sha = new SHA1();
114-
sha.update(data);
115-
116-
return sha.digest();
117-
}
118-
119-
constructor() {
120-
this.length = 0;
121-
122-
this.buffer = new Uint8Array(SHA1.BLOCK_SIZE);
123-
this.bufferDV = new DataView(this.buffer.buffer);
124-
this.bufferLength = 0;
125-
126-
this.bigBlock32 = new DataView(new ArrayBuffer(320)); // 80 * 4 = 320;
127-
}
128-
129-
update(data: string): void;
130-
update(data: Uint8Array): void;
131-
update(data: ArrayBuffer): void;
132-
update(data: DataView): void;
133-
update(arg: any): void {
134-
if (!this.buffer || !this.bufferDV) {
135-
throw new Error('Digest already computed.');
136-
}
137-
138-
let data: Uint8Array;
139-
140-
if (isString(arg)) {
141-
data = new Uint8Array(toUint8ArrayBuffer(<string>arg));
142-
} else if (arg instanceof ArrayBuffer) {
143-
data = new Uint8Array(arg);
144-
} else if (arg instanceof DataView) {
145-
data = new Uint8Array((<DataView>arg).buffer);
146-
} else {
147-
data = <Uint8Array>arg;
148-
}
149-
150-
let bytesRead = 0, totalBytesRead = 0;
151-
152-
while (totalBytesRead < data.byteLength) {
153-
bytesRead = copy(this.buffer, this.bufferLength, data, totalBytesRead, data.byteLength);
154-
155-
this.bufferLength += bytesRead;
156-
totalBytesRead += bytesRead;
157-
158-
if (this.bufferLength === SHA1.BLOCK_SIZE) {
159-
this.step(this.bufferDV);
160-
this.bufferLength = 0;
161-
}
162-
}
163-
164-
this.length += totalBytesRead;
165-
}
166-
167-
digest(): string {
168-
if (this.buffer) {
169-
this.wrapUp();
170-
}
171-
172-
return toHexString(this.h0) + toHexString(this.h1) + toHexString(this.h2) + toHexString(this.h3) + toHexString(this.h4);
173-
}
174-
175-
private wrapUp(): void {
176-
if (!this.buffer || !this.bufferDV) {
177-
return; // already wrapped up
178-
}
179-
180-
this.buffer[this.bufferLength++] = 0x80;
181-
fill(this.buffer, this.bufferLength);
182-
183-
if (this.bufferLength > 56) {
184-
this.step(this.bufferDV);
185-
fill(this.buffer);
186-
}
187-
188-
let ml = multiply64(8, this.length);
189-
this.bufferDV.setUint32(56, ml[0], false);
190-
this.bufferDV.setUint32(60, ml[1], false);
191-
192-
this.step(this.bufferDV);
193-
194-
this.buffer = null;
195-
this.bufferDV = null;
196-
this.bufferLength = -1;
197-
}
198-
199-
private step(data: DataView): void {
200-
for (let j = 0; j < 64 /* 16*4 */; j += 4) {
201-
this.bigBlock32.setUint32(j, data.getUint32(j, false), false);
202-
}
203-
204-
for (let j = 64; j < 320 /* 80*4 */; j += 4) {
205-
this.bigBlock32.setUint32(j, leftRotate((this.bigBlock32.getUint32(j - 12, false) ^ this.bigBlock32.getUint32(j - 32, false) ^ this.bigBlock32.getUint32(j - 56, false) ^ this.bigBlock32.getUint32(j - 64, false)), 1), false);
206-
}
207-
208-
let a = this.h0;
209-
let b = this.h1;
210-
let c = this.h2;
211-
let d = this.h3;
212-
let e = this.h4;
213-
214-
let f: number, k: number;
215-
let temp: number;
216-
217-
for (let j = 0; j < 80; j++) {
218-
if (j < 20) {
219-
f = (b & c) | ((~b) & d);
220-
k = 0x5A827999;
221-
} else if (j < 40) {
222-
f = b ^ c ^ d;
223-
k = 0x6ED9EBA1;
224-
} else if (j < 60) {
225-
f = (b & c) | (b & d) | (c & d);
226-
k = 0x8F1BBCDC;
227-
} else {
228-
f = b ^ c ^ d;
229-
k = 0xCA62C1D6;
230-
}
231-
232-
temp = (leftRotate(a, 5) + f + e + k + this.bigBlock32.getUint32(j * 4, false)) & 0xFFFFFFFF;
233-
e = d;
234-
d = c;
235-
c = leftRotate(b, 30);
236-
b = a;
237-
a = temp;
238-
}
239-
240-
this.h0 = (this.h0 + a) & 0xFFFFFFFF;
241-
this.h1 = (this.h1 + b) & 0xFFFFFFFF;
242-
this.h2 = (this.h2 + c) & 0xFFFFFFFF;
243-
this.h3 = (this.h3 + d) & 0xFFFFFFFF;
244-
this.h4 = (this.h4 + e) & 0xFFFFFFFF;
245-
}
246-
}
247-
248-
function leftPad(value: string, length: number, char: string = '0'): string {
249-
return new Array(length - value.length + 1).join(char) + value;
250-
}
251-
252-
function toHexString(value: number, bitsize: number = 32): string {
253-
return leftPad((value >>> 0).toString(16), bitsize / 4);
254-
}
255-
256-
function leftRotate(value: number, bits: number, totalBits: number = 32): number {
257-
258-
// delta + bits = totalBits
259-
let delta = totalBits - bits;
260-
261-
// All ones, expect `delta` zeros aligned to the right
262-
let mask = ~((1 << delta) - 1);
263-
264-
// Join (value left-shifted `bits` bits) with (masked value right-shifted `delta` bits)
265-
return ((value << bits) | ((mask & value) >>> delta)) >>> 0;
266-
}
267-
268-
function multiply64(a: number, b: number): number[] {
269-
/* A1 A0 => A
270-
* B1 B0 => B
271-
* B0 * A1 B0 * A0
272-
* B1 * A1 B1 * A0
273-
* C3 C2 C1 C0 => C
274-
*/
275-
276-
let a0 = a & 0xFFFF, a1 = a >>> 16;
277-
let b0 = b & 0xFFFF, b1 = b >>> 16;
278-
let c0 = 0, c1 = 0, c2 = 0, c3 = 0;
279-
280-
let x = b0 * a0;
281-
c0 += x & 0xFFFF;
282-
c1 += x >>> 16;
283-
284-
x = b0 * a1;
285-
c1 += x & 0xFFFF;
286-
c2 += x >>> 16;
287-
288-
x = b1 * a0;
289-
c1 += x & 0xFFFF;
290-
c2 += x >>> 16;
291-
292-
c2 += c1 >>> 16;
293-
c1 = c1 & 0xFFFF;
294-
295-
x = b1 * a1;
296-
c2 += x & 0xFFFF;
297-
c3 += x >>> 16;
298-
299-
c3 += c2 >>> 16;
300-
c2 = c2 & 0xFFFF;
301-
302-
return [(c3 << 16 | c2) >>> 0, (c1 << 16 | c0) >>> 0];
303-
}
304-
305-
function copy(dest: Uint8Array, destIndex: number, src: Uint8Array, srcIndex: number, count: number): number {
306-
const len = Math.min(dest.byteLength - destIndex, src.byteLength - srcIndex, count);
307-
308-
for (let i = 0; i < len; i++) {
309-
dest[destIndex + i] = src[srcIndex + i];
310-
}
311-
312-
return len;
313-
}
314-
315-
function fill(dest: Uint8Array, index: number = 0, count: number = dest.byteLength, value: number = 0): void {
316-
for (let i = 0; i < count; i++) {
317-
dest[index + i] = value;
318-
}
319-
}
320-
321-
//#endregion

src/vs/base/test/common/hash.test.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55
import * as assert from 'assert';
6-
import { hash, computeSHA1Hash } from 'vs/base/common/hash';
6+
import { hash } from 'vs/base/common/hash';
77

88
suite('Hash', () => {
99
test('string', () => {
@@ -43,12 +43,4 @@ suite('Hash', () => {
4343
assert.notEqual(hash({ 'foo': 'bar' }), hash({ 'foo': 'bar2' }));
4444
assert.notEqual(hash({}), hash([]));
4545
});
46-
47-
test('computeSHA1Hash', () => {
48-
assert.equal(computeSHA1Hash(''), 'da39a3ee5e6b4b0d3255bfef95601890afd80709');
49-
assert.equal(computeSHA1Hash('hello world'), '2aae6c35c94fcfb415dbe95f408b9ce91ee846ed');
50-
assert.equal(computeSHA1Hash('da39a3ee5e6b4b0d3255bfef95601890afd80709'), '10a34637ad661d98ba3344717656fcc76209c2f8');
51-
assert.equal(computeSHA1Hash('2aae6c35c94fcfb415dbe95f408b9ce91ee846ed'), 'd6b0d82cea4269b51572b8fab43adcee9fc3cf9a');
52-
assert.equal(computeSHA1Hash('öäü_?ß()<>ÖÄÜ'), 'b64beaeff9e317b0193c8e40a2431b210388eba9');
53-
});
5446
});

src/vs/platform/telemetry/common/telemetryUtils.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { IDisposable } from 'vs/base/common/lifecycle';
7-
import { guessMimeTypes } from 'vs/base/common/mime';
8-
import { extname } from 'vs/base/common/path';
9-
import { URI } from 'vs/base/common/uri';
107
import { IConfigurationService, ConfigurationTarget, ConfigurationTargetToString } from 'vs/platform/configuration/common/configuration';
118
import { IKeybindingService, KeybindingSource } from 'vs/platform/keybinding/common/keybinding';
129
import { ITelemetryService, ITelemetryInfo, ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
@@ -77,11 +74,6 @@ export interface URIDescriptor {
7774
path?: string;
7875
}
7976

80-
export function telemetryURIDescriptor(uri: URI, hashPath: (path: string) => string): URIDescriptor {
81-
const fsPath = uri && uri.fsPath;
82-
return fsPath ? { mimeType: guessMimeTypes(fsPath).join(', '), scheme: uri.scheme, ext: extname(fsPath), path: hashPath(fsPath) } : {};
83-
}
84-
8577
/**
8678
* Only add settings that cannot contain any personal/private information of users (PII).
8779
*/

0 commit comments

Comments
 (0)