Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 3.5 KiB |
@ -1,51 +0,0 @@ |
|||||
import { Int10 } from "./int10"; |
|
||||
export declare class Stream { |
|
||||
constructor(enc: Stream | number[], pos?: number); |
|
||||
private enc; |
|
||||
pos: number; |
|
||||
get(pos?: number): number; |
|
||||
hexDigits: string; |
|
||||
hexByte(b: number): string; |
|
||||
hexDump(start: number, end: number, raw: boolean): string; |
|
||||
isASCII(start: number, end: number): boolean; |
|
||||
parseStringISO(start: number, end: number): string; |
|
||||
parseStringUTF(start: number, end: number): string; |
|
||||
parseStringBMP(start: number, end: number): string; |
|
||||
parseTime(start: number, end: number, shortYear: boolean): string; |
|
||||
parseInteger(start: number, end: number): string | 0 | -1; |
|
||||
parseBitString(start: number, end: number, maxLength: number): string; |
|
||||
parseOctetString(start: number, end: number, maxLength: number): string; |
|
||||
parseOID(start: number, end: number, maxLength: number): string; |
|
||||
} |
|
||||
export declare class ASN1 { |
|
||||
constructor(stream: Stream, header: number, length: number, tag: ASN1Tag, sub: ASN1[]); |
|
||||
private stream; |
|
||||
private header; |
|
||||
private length; |
|
||||
private tag; |
|
||||
sub: ASN1[]; |
|
||||
typeName(): string; |
|
||||
content(maxLength: number): string | 0 | -1; |
|
||||
toString(): string; |
|
||||
toPrettyString(indent: string): string; |
|
||||
posStart(): number; |
|
||||
posContent(): number; |
|
||||
posEnd(): number; |
|
||||
toHexString(): string; |
|
||||
static decodeLength(stream: Stream): number; |
|
||||
/** |
|
||||
* Retrieve the hexadecimal value (as a string) of the current ASN.1 element |
|
||||
* @returns {string} |
|
||||
* @public |
|
||||
*/ |
|
||||
getHexStringValue(): string; |
|
||||
static decode(str: Stream | number[]): ASN1; |
|
||||
} |
|
||||
export declare class ASN1Tag { |
|
||||
constructor(stream: Stream); |
|
||||
tagClass: number; |
|
||||
tagConstructed: boolean; |
|
||||
tagNumber: number | Int10; |
|
||||
isUniversal(): boolean; |
|
||||
isEOC(): boolean; |
|
||||
} |
|
@ -1,565 +0,0 @@ |
|||||
// ASN.1 JavaScript decoder
|
|
||||
// Copyright (c) 2008-2014 Lapo Luchini <lapo@lapo.it>
|
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||
// copyright notice and this permission notice appear in all copies.
|
|
||||
//
|
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||
/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */ |
|
||||
/*global oids */ |
|
||||
import { Int10 } from "./int10"; |
|
||||
var ellipsis = "\u2026"; |
|
||||
var reTimeS = /^(\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/; |
|
||||
var reTimeL = /^(\d\d\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/; |
|
||||
function stringCut(str, len) { |
|
||||
if (str.length > len) { |
|
||||
str = str.substring(0, len) + ellipsis; |
|
||||
} |
|
||||
return str; |
|
||||
} |
|
||||
var Stream = /** @class */ (function () { |
|
||||
function Stream(enc, pos) { |
|
||||
this.hexDigits = "0123456789ABCDEF"; |
|
||||
if (enc instanceof Stream) { |
|
||||
this.enc = enc.enc; |
|
||||
this.pos = enc.pos; |
|
||||
} |
|
||||
else { |
|
||||
// enc should be an array or a binary string
|
|
||||
this.enc = enc; |
|
||||
this.pos = pos; |
|
||||
} |
|
||||
} |
|
||||
Stream.prototype.get = function (pos) { |
|
||||
if (pos === undefined) { |
|
||||
pos = this.pos++; |
|
||||
} |
|
||||
if (pos >= this.enc.length) { |
|
||||
throw new Error("Requesting byte offset ".concat(pos, " on a stream of length ").concat(this.enc.length)); |
|
||||
} |
|
||||
return ("string" === typeof this.enc) ? this.enc.charCodeAt(pos) : this.enc[pos]; |
|
||||
}; |
|
||||
Stream.prototype.hexByte = function (b) { |
|
||||
return this.hexDigits.charAt((b >> 4) & 0xF) + this.hexDigits.charAt(b & 0xF); |
|
||||
}; |
|
||||
Stream.prototype.hexDump = function (start, end, raw) { |
|
||||
var s = ""; |
|
||||
for (var i = start; i < end; ++i) { |
|
||||
s += this.hexByte(this.get(i)); |
|
||||
if (raw !== true) { |
|
||||
switch (i & 0xF) { |
|
||||
case 0x7: |
|
||||
s += " "; |
|
||||
break; |
|
||||
case 0xF: |
|
||||
s += "\n"; |
|
||||
break; |
|
||||
default: |
|
||||
s += " "; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return s; |
|
||||
}; |
|
||||
Stream.prototype.isASCII = function (start, end) { |
|
||||
for (var i = start; i < end; ++i) { |
|
||||
var c = this.get(i); |
|
||||
if (c < 32 || c > 176) { |
|
||||
return false; |
|
||||
} |
|
||||
} |
|
||||
return true; |
|
||||
}; |
|
||||
Stream.prototype.parseStringISO = function (start, end) { |
|
||||
var s = ""; |
|
||||
for (var i = start; i < end; ++i) { |
|
||||
s += String.fromCharCode(this.get(i)); |
|
||||
} |
|
||||
return s; |
|
||||
}; |
|
||||
Stream.prototype.parseStringUTF = function (start, end) { |
|
||||
var s = ""; |
|
||||
for (var i = start; i < end;) { |
|
||||
var c = this.get(i++); |
|
||||
if (c < 128) { |
|
||||
s += String.fromCharCode(c); |
|
||||
} |
|
||||
else if ((c > 191) && (c < 224)) { |
|
||||
s += String.fromCharCode(((c & 0x1F) << 6) | (this.get(i++) & 0x3F)); |
|
||||
} |
|
||||
else { |
|
||||
s += String.fromCharCode(((c & 0x0F) << 12) | ((this.get(i++) & 0x3F) << 6) | (this.get(i++) & 0x3F)); |
|
||||
} |
|
||||
} |
|
||||
return s; |
|
||||
}; |
|
||||
Stream.prototype.parseStringBMP = function (start, end) { |
|
||||
var str = ""; |
|
||||
var hi; |
|
||||
var lo; |
|
||||
for (var i = start; i < end;) { |
|
||||
hi = this.get(i++); |
|
||||
lo = this.get(i++); |
|
||||
str += String.fromCharCode((hi << 8) | lo); |
|
||||
} |
|
||||
return str; |
|
||||
}; |
|
||||
Stream.prototype.parseTime = function (start, end, shortYear) { |
|
||||
var s = this.parseStringISO(start, end); |
|
||||
var m = (shortYear ? reTimeS : reTimeL).exec(s); |
|
||||
if (!m) { |
|
||||
return "Unrecognized time: " + s; |
|
||||
} |
|
||||
if (shortYear) { |
|
||||
// to avoid querying the timer, use the fixed range [1970, 2069]
|
|
||||
// it will conform with ITU X.400 [-10, +40] sliding window until 2030
|
|
||||
m[1] = +m[1]; |
|
||||
m[1] += (+m[1] < 70) ? 2000 : 1900; |
|
||||
} |
|
||||
s = m[1] + "-" + m[2] + "-" + m[3] + " " + m[4]; |
|
||||
if (m[5]) { |
|
||||
s += ":" + m[5]; |
|
||||
if (m[6]) { |
|
||||
s += ":" + m[6]; |
|
||||
if (m[7]) { |
|
||||
s += "." + m[7]; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
if (m[8]) { |
|
||||
s += " UTC"; |
|
||||
if (m[8] != "Z") { |
|
||||
s += m[8]; |
|
||||
if (m[9]) { |
|
||||
s += ":" + m[9]; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return s; |
|
||||
}; |
|
||||
Stream.prototype.parseInteger = function (start, end) { |
|
||||
var v = this.get(start); |
|
||||
var neg = (v > 127); |
|
||||
var pad = neg ? 255 : 0; |
|
||||
var len; |
|
||||
var s = ""; |
|
||||
// skip unuseful bits (not allowed in DER)
|
|
||||
while (v == pad && ++start < end) { |
|
||||
v = this.get(start); |
|
||||
} |
|
||||
len = end - start; |
|
||||
if (len === 0) { |
|
||||
return neg ? -1 : 0; |
|
||||
} |
|
||||
// show bit length of huge integers
|
|
||||
if (len > 4) { |
|
||||
s = v; |
|
||||
len <<= 3; |
|
||||
while (((+s ^ pad) & 0x80) == 0) { |
|
||||
s = +s << 1; |
|
||||
--len; |
|
||||
} |
|
||||
s = "(" + len + " bit)\n"; |
|
||||
} |
|
||||
// decode the integer
|
|
||||
if (neg) { |
|
||||
v = v - 256; |
|
||||
} |
|
||||
var n = new Int10(v); |
|
||||
for (var i = start + 1; i < end; ++i) { |
|
||||
n.mulAdd(256, this.get(i)); |
|
||||
} |
|
||||
return s + n.toString(); |
|
||||
}; |
|
||||
Stream.prototype.parseBitString = function (start, end, maxLength) { |
|
||||
var unusedBit = this.get(start); |
|
||||
var lenBit = ((end - start - 1) << 3) - unusedBit; |
|
||||
var intro = "(" + lenBit + " bit)\n"; |
|
||||
var s = ""; |
|
||||
for (var i = start + 1; i < end; ++i) { |
|
||||
var b = this.get(i); |
|
||||
var skip = (i == end - 1) ? unusedBit : 0; |
|
||||
for (var j = 7; j >= skip; --j) { |
|
||||
s += (b >> j) & 1 ? "1" : "0"; |
|
||||
} |
|
||||
if (s.length > maxLength) { |
|
||||
return intro + stringCut(s, maxLength); |
|
||||
} |
|
||||
} |
|
||||
return intro + s; |
|
||||
}; |
|
||||
Stream.prototype.parseOctetString = function (start, end, maxLength) { |
|
||||
if (this.isASCII(start, end)) { |
|
||||
return stringCut(this.parseStringISO(start, end), maxLength); |
|
||||
} |
|
||||
var len = end - start; |
|
||||
var s = "(" + len + " byte)\n"; |
|
||||
maxLength /= 2; // we work in bytes
|
|
||||
if (len > maxLength) { |
|
||||
end = start + maxLength; |
|
||||
} |
|
||||
for (var i = start; i < end; ++i) { |
|
||||
s += this.hexByte(this.get(i)); |
|
||||
} |
|
||||
if (len > maxLength) { |
|
||||
s += ellipsis; |
|
||||
} |
|
||||
return s; |
|
||||
}; |
|
||||
Stream.prototype.parseOID = function (start, end, maxLength) { |
|
||||
var s = ""; |
|
||||
var n = new Int10(); |
|
||||
var bits = 0; |
|
||||
for (var i = start; i < end; ++i) { |
|
||||
var v = this.get(i); |
|
||||
n.mulAdd(128, v & 0x7F); |
|
||||
bits += 7; |
|
||||
if (!(v & 0x80)) { // finished
|
|
||||
if (s === "") { |
|
||||
n = n.simplify(); |
|
||||
if (n instanceof Int10) { |
|
||||
n.sub(80); |
|
||||
s = "2." + n.toString(); |
|
||||
} |
|
||||
else { |
|
||||
var m = n < 80 ? n < 40 ? 0 : 1 : 2; |
|
||||
s = m + "." + (n - m * 40); |
|
||||
} |
|
||||
} |
|
||||
else { |
|
||||
s += "." + n.toString(); |
|
||||
} |
|
||||
if (s.length > maxLength) { |
|
||||
return stringCut(s, maxLength); |
|
||||
} |
|
||||
n = new Int10(); |
|
||||
bits = 0; |
|
||||
} |
|
||||
} |
|
||||
if (bits > 0) { |
|
||||
s += ".incomplete"; |
|
||||
} |
|
||||
return s; |
|
||||
}; |
|
||||
return Stream; |
|
||||
}()); |
|
||||
export { Stream }; |
|
||||
var ASN1 = /** @class */ (function () { |
|
||||
function ASN1(stream, header, length, tag, sub) { |
|
||||
if (!(tag instanceof ASN1Tag)) { |
|
||||
throw new Error("Invalid tag value."); |
|
||||
} |
|
||||
this.stream = stream; |
|
||||
this.header = header; |
|
||||
this.length = length; |
|
||||
this.tag = tag; |
|
||||
this.sub = sub; |
|
||||
} |
|
||||
ASN1.prototype.typeName = function () { |
|
||||
switch (this.tag.tagClass) { |
|
||||
case 0: // universal
|
|
||||
switch (this.tag.tagNumber) { |
|
||||
case 0x00: |
|
||||
return "EOC"; |
|
||||
case 0x01: |
|
||||
return "BOOLEAN"; |
|
||||
case 0x02: |
|
||||
return "INTEGER"; |
|
||||
case 0x03: |
|
||||
return "BIT_STRING"; |
|
||||
case 0x04: |
|
||||
return "OCTET_STRING"; |
|
||||
case 0x05: |
|
||||
return "NULL"; |
|
||||
case 0x06: |
|
||||
return "OBJECT_IDENTIFIER"; |
|
||||
case 0x07: |
|
||||
return "ObjectDescriptor"; |
|
||||
case 0x08: |
|
||||
return "EXTERNAL"; |
|
||||
case 0x09: |
|
||||
return "REAL"; |
|
||||
case 0x0A: |
|
||||
return "ENUMERATED"; |
|
||||
case 0x0B: |
|
||||
return "EMBEDDED_PDV"; |
|
||||
case 0x0C: |
|
||||
return "UTF8String"; |
|
||||
case 0x10: |
|
||||
return "SEQUENCE"; |
|
||||
case 0x11: |
|
||||
return "SET"; |
|
||||
case 0x12: |
|
||||
return "NumericString"; |
|
||||
case 0x13: |
|
||||
return "PrintableString"; // ASCII subset
|
|
||||
case 0x14: |
|
||||
return "TeletexString"; // aka T61String
|
|
||||
case 0x15: |
|
||||
return "VideotexString"; |
|
||||
case 0x16: |
|
||||
return "IA5String"; // ASCII
|
|
||||
case 0x17: |
|
||||
return "UTCTime"; |
|
||||
case 0x18: |
|
||||
return "GeneralizedTime"; |
|
||||
case 0x19: |
|
||||
return "GraphicString"; |
|
||||
case 0x1A: |
|
||||
return "VisibleString"; // ASCII subset
|
|
||||
case 0x1B: |
|
||||
return "GeneralString"; |
|
||||
case 0x1C: |
|
||||
return "UniversalString"; |
|
||||
case 0x1E: |
|
||||
return "BMPString"; |
|
||||
} |
|
||||
return "Universal_" + this.tag.tagNumber.toString(); |
|
||||
case 1: |
|
||||
return "Application_" + this.tag.tagNumber.toString(); |
|
||||
case 2: |
|
||||
return "[" + this.tag.tagNumber.toString() + "]"; // Context
|
|
||||
case 3: |
|
||||
return "Private_" + this.tag.tagNumber.toString(); |
|
||||
} |
|
||||
}; |
|
||||
ASN1.prototype.content = function (maxLength) { |
|
||||
if (this.tag === undefined) { |
|
||||
return null; |
|
||||
} |
|
||||
if (maxLength === undefined) { |
|
||||
maxLength = Infinity; |
|
||||
} |
|
||||
var content = this.posContent(); |
|
||||
var len = Math.abs(this.length); |
|
||||
if (!this.tag.isUniversal()) { |
|
||||
if (this.sub !== null) { |
|
||||
return "(" + this.sub.length + " elem)"; |
|
||||
} |
|
||||
return this.stream.parseOctetString(content, content + len, maxLength); |
|
||||
} |
|
||||
switch (this.tag.tagNumber) { |
|
||||
case 0x01: // BOOLEAN
|
|
||||
return (this.stream.get(content) === 0) ? "false" : "true"; |
|
||||
case 0x02: // INTEGER
|
|
||||
return this.stream.parseInteger(content, content + len); |
|
||||
case 0x03: // BIT_STRING
|
|
||||
return this.sub ? "(" + this.sub.length + " elem)" : |
|
||||
this.stream.parseBitString(content, content + len, maxLength); |
|
||||
case 0x04: // OCTET_STRING
|
|
||||
return this.sub ? "(" + this.sub.length + " elem)" : |
|
||||
this.stream.parseOctetString(content, content + len, maxLength); |
|
||||
// case 0x05: // NULL
|
|
||||
case 0x06: // OBJECT_IDENTIFIER
|
|
||||
return this.stream.parseOID(content, content + len, maxLength); |
|
||||
// case 0x07: // ObjectDescriptor
|
|
||||
// case 0x08: // EXTERNAL
|
|
||||
// case 0x09: // REAL
|
|
||||
// case 0x0A: // ENUMERATED
|
|
||||
// case 0x0B: // EMBEDDED_PDV
|
|
||||
case 0x10: // SEQUENCE
|
|
||||
case 0x11: // SET
|
|
||||
if (this.sub !== null) { |
|
||||
return "(" + this.sub.length + " elem)"; |
|
||||
} |
|
||||
else { |
|
||||
return "(no elem)"; |
|
||||
} |
|
||||
case 0x0C: // UTF8String
|
|
||||
return stringCut(this.stream.parseStringUTF(content, content + len), maxLength); |
|
||||
case 0x12: // NumericString
|
|
||||
case 0x13: // PrintableString
|
|
||||
case 0x14: // TeletexString
|
|
||||
case 0x15: // VideotexString
|
|
||||
case 0x16: // IA5String
|
|
||||
// case 0x19: // GraphicString
|
|
||||
case 0x1A: // VisibleString
|
|
||||
// case 0x1B: // GeneralString
|
|
||||
// case 0x1C: // UniversalString
|
|
||||
return stringCut(this.stream.parseStringISO(content, content + len), maxLength); |
|
||||
case 0x1E: // BMPString
|
|
||||
return stringCut(this.stream.parseStringBMP(content, content + len), maxLength); |
|
||||
case 0x17: // UTCTime
|
|
||||
case 0x18: // GeneralizedTime
|
|
||||
return this.stream.parseTime(content, content + len, (this.tag.tagNumber == 0x17)); |
|
||||
} |
|
||||
return null; |
|
||||
}; |
|
||||
ASN1.prototype.toString = function () { |
|
||||
return this.typeName() + "@" + this.stream.pos + "[header:" + this.header + ",length:" + this.length + ",sub:" + ((this.sub === null) ? "null" : this.sub.length) + "]"; |
|
||||
}; |
|
||||
ASN1.prototype.toPrettyString = function (indent) { |
|
||||
if (indent === undefined) { |
|
||||
indent = ""; |
|
||||
} |
|
||||
var s = indent + this.typeName() + " @" + this.stream.pos; |
|
||||
if (this.length >= 0) { |
|
||||
s += "+"; |
|
||||
} |
|
||||
s += this.length; |
|
||||
if (this.tag.tagConstructed) { |
|
||||
s += " (constructed)"; |
|
||||
} |
|
||||
else if ((this.tag.isUniversal() && ((this.tag.tagNumber == 0x03) || (this.tag.tagNumber == 0x04))) && (this.sub !== null)) { |
|
||||
s += " (encapsulates)"; |
|
||||
} |
|
||||
s += "\n"; |
|
||||
if (this.sub !== null) { |
|
||||
indent += " "; |
|
||||
for (var i = 0, max = this.sub.length; i < max; ++i) { |
|
||||
s += this.sub[i].toPrettyString(indent); |
|
||||
} |
|
||||
} |
|
||||
return s; |
|
||||
}; |
|
||||
ASN1.prototype.posStart = function () { |
|
||||
return this.stream.pos; |
|
||||
}; |
|
||||
ASN1.prototype.posContent = function () { |
|
||||
return this.stream.pos + this.header; |
|
||||
}; |
|
||||
ASN1.prototype.posEnd = function () { |
|
||||
return this.stream.pos + this.header + Math.abs(this.length); |
|
||||
}; |
|
||||
ASN1.prototype.toHexString = function () { |
|
||||
return this.stream.hexDump(this.posStart(), this.posEnd(), true); |
|
||||
}; |
|
||||
ASN1.decodeLength = function (stream) { |
|
||||
var buf = stream.get(); |
|
||||
var len = buf & 0x7F; |
|
||||
if (len == buf) { |
|
||||
return len; |
|
||||
} |
|
||||
// no reason to use Int10, as it would be a huge buffer anyways
|
|
||||
if (len > 6) { |
|
||||
throw new Error("Length over 48 bits not supported at position " + (stream.pos - 1)); |
|
||||
} |
|
||||
if (len === 0) { |
|
||||
return null; |
|
||||
} // undefined
|
|
||||
buf = 0; |
|
||||
for (var i = 0; i < len; ++i) { |
|
||||
buf = (buf * 256) + stream.get(); |
|
||||
} |
|
||||
return buf; |
|
||||
}; |
|
||||
/** |
|
||||
* Retrieve the hexadecimal value (as a string) of the current ASN.1 element |
|
||||
* @returns {string} |
|
||||
* @public |
|
||||
*/ |
|
||||
ASN1.prototype.getHexStringValue = function () { |
|
||||
var hexString = this.toHexString(); |
|
||||
var offset = this.header * 2; |
|
||||
var length = this.length * 2; |
|
||||
return hexString.substr(offset, length); |
|
||||
}; |
|
||||
ASN1.decode = function (str) { |
|
||||
var stream; |
|
||||
if (!(str instanceof Stream)) { |
|
||||
stream = new Stream(str, 0); |
|
||||
} |
|
||||
else { |
|
||||
stream = str; |
|
||||
} |
|
||||
var streamStart = new Stream(stream); |
|
||||
var tag = new ASN1Tag(stream); |
|
||||
var len = ASN1.decodeLength(stream); |
|
||||
var start = stream.pos; |
|
||||
var header = start - streamStart.pos; |
|
||||
var sub = null; |
|
||||
var getSub = function () { |
|
||||
var ret = []; |
|
||||
if (len !== null) { |
|
||||
// definite length
|
|
||||
var end = start + len; |
|
||||
while (stream.pos < end) { |
|
||||
ret[ret.length] = ASN1.decode(stream); |
|
||||
} |
|
||||
if (stream.pos != end) { |
|
||||
throw new Error("Content size is not correct for container starting at offset " + start); |
|
||||
} |
|
||||
} |
|
||||
else { |
|
||||
// undefined length
|
|
||||
try { |
|
||||
for (;;) { |
|
||||
var s = ASN1.decode(stream); |
|
||||
if (s.tag.isEOC()) { |
|
||||
break; |
|
||||
} |
|
||||
ret[ret.length] = s; |
|
||||
} |
|
||||
len = start - stream.pos; // undefined lengths are represented as negative values
|
|
||||
} |
|
||||
catch (e) { |
|
||||
throw new Error("Exception while decoding undefined length content: " + e); |
|
||||
} |
|
||||
} |
|
||||
return ret; |
|
||||
}; |
|
||||
if (tag.tagConstructed) { |
|
||||
// must have valid content
|
|
||||
sub = getSub(); |
|
||||
} |
|
||||
else if (tag.isUniversal() && ((tag.tagNumber == 0x03) || (tag.tagNumber == 0x04))) { |
|
||||
// sometimes BitString and OctetString are used to encapsulate ASN.1
|
|
||||
try { |
|
||||
if (tag.tagNumber == 0x03) { |
|
||||
if (stream.get() != 0) { |
|
||||
throw new Error("BIT STRINGs with unused bits cannot encapsulate."); |
|
||||
} |
|
||||
} |
|
||||
sub = getSub(); |
|
||||
for (var i = 0; i < sub.length; ++i) { |
|
||||
if (sub[i].tag.isEOC()) { |
|
||||
throw new Error("EOC is not supposed to be actual content."); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
catch (e) { |
|
||||
// but silently ignore when they don't
|
|
||||
sub = null; |
|
||||
} |
|
||||
} |
|
||||
if (sub === null) { |
|
||||
if (len === null) { |
|
||||
throw new Error("We can't skip over an invalid tag with undefined length at offset " + start); |
|
||||
} |
|
||||
stream.pos = start + Math.abs(len); |
|
||||
} |
|
||||
return new ASN1(streamStart, header, len, tag, sub); |
|
||||
}; |
|
||||
return ASN1; |
|
||||
}()); |
|
||||
export { ASN1 }; |
|
||||
var ASN1Tag = /** @class */ (function () { |
|
||||
function ASN1Tag(stream) { |
|
||||
var buf = stream.get(); |
|
||||
this.tagClass = buf >> 6; |
|
||||
this.tagConstructed = ((buf & 0x20) !== 0); |
|
||||
this.tagNumber = buf & 0x1F; |
|
||||
if (this.tagNumber == 0x1F) { // long tag
|
|
||||
var n = new Int10(); |
|
||||
do { |
|
||||
buf = stream.get(); |
|
||||
n.mulAdd(128, buf & 0x7F); |
|
||||
} while (buf & 0x80); |
|
||||
this.tagNumber = n.simplify(); |
|
||||
} |
|
||||
} |
|
||||
ASN1Tag.prototype.isUniversal = function () { |
|
||||
return this.tagClass === 0x00; |
|
||||
}; |
|
||||
ASN1Tag.prototype.isEOC = function () { |
|
||||
return this.tagClass === 0x00 && this.tagNumber === 0x00; |
|
||||
}; |
|
||||
return ASN1Tag; |
|
||||
}()); |
|
||||
export { ASN1Tag }; |
|
@ -1,5 +0,0 @@ |
|||||
export declare const Base64: { |
|
||||
decode(a: string): number[]; |
|
||||
re: RegExp; |
|
||||
unarmor(a: string): number[]; |
|
||||
}; |
|
@ -1,88 +0,0 @@ |
|||||
// Base64 JavaScript decoder
|
|
||||
// Copyright (c) 2008-2013 Lapo Luchini <lapo@lapo.it>
|
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||
// copyright notice and this permission notice appear in all copies.
|
|
||||
//
|
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||
/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */ |
|
||||
var decoder; |
|
||||
export var Base64 = { |
|
||||
decode: function (a) { |
|
||||
var i; |
|
||||
if (decoder === undefined) { |
|
||||
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
|
||||
var ignore = "= \f\n\r\t\u00A0\u2028\u2029"; |
|
||||
decoder = Object.create(null); |
|
||||
for (i = 0; i < 64; ++i) { |
|
||||
decoder[b64.charAt(i)] = i; |
|
||||
} |
|
||||
decoder['-'] = 62; //+
|
|
||||
decoder['_'] = 63; //-
|
|
||||
for (i = 0; i < ignore.length; ++i) { |
|
||||
decoder[ignore.charAt(i)] = -1; |
|
||||
} |
|
||||
} |
|
||||
var out = []; |
|
||||
var bits = 0; |
|
||||
var char_count = 0; |
|
||||
for (i = 0; i < a.length; ++i) { |
|
||||
var c = a.charAt(i); |
|
||||
if (c == "=") { |
|
||||
break; |
|
||||
} |
|
||||
c = decoder[c]; |
|
||||
if (c == -1) { |
|
||||
continue; |
|
||||
} |
|
||||
if (c === undefined) { |
|
||||
throw new Error("Illegal character at offset " + i); |
|
||||
} |
|
||||
bits |= c; |
|
||||
if (++char_count >= 4) { |
|
||||
out[out.length] = (bits >> 16); |
|
||||
out[out.length] = (bits >> 8) & 0xFF; |
|
||||
out[out.length] = bits & 0xFF; |
|
||||
bits = 0; |
|
||||
char_count = 0; |
|
||||
} |
|
||||
else { |
|
||||
bits <<= 6; |
|
||||
} |
|
||||
} |
|
||||
switch (char_count) { |
|
||||
case 1: |
|
||||
throw new Error("Base64 encoding incomplete: at least 2 bits missing"); |
|
||||
case 2: |
|
||||
out[out.length] = (bits >> 10); |
|
||||
break; |
|
||||
case 3: |
|
||||
out[out.length] = (bits >> 16); |
|
||||
out[out.length] = (bits >> 8) & 0xFF; |
|
||||
break; |
|
||||
} |
|
||||
return out; |
|
||||
}, |
|
||||
re: /-----BEGIN [^-]+-----([A-Za-z0-9+\/=\s]+)-----END [^-]+-----|begin-base64[^\n]+\n([A-Za-z0-9+\/=\s]+)====/, |
|
||||
unarmor: function (a) { |
|
||||
var m = Base64.re.exec(a); |
|
||||
if (m) { |
|
||||
if (m[1]) { |
|
||||
a = m[1]; |
|
||||
} |
|
||||
else if (m[2]) { |
|
||||
a = m[2]; |
|
||||
} |
|
||||
else { |
|
||||
throw new Error("RegExp out of sync"); |
|
||||
} |
|
||||
} |
|
||||
return Base64.decode(a); |
|
||||
} |
|
||||
}; |
|
@ -1,3 +0,0 @@ |
|||||
export declare const Hex: { |
|
||||
decode(a: string): number[]; |
|
||||
}; |
|
@ -1,64 +0,0 @@ |
|||||
// Hex JavaScript decoder
|
|
||||
// Copyright (c) 2008-2013 Lapo Luchini <lapo@lapo.it>
|
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||
// copyright notice and this permission notice appear in all copies.
|
|
||||
//
|
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||
/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */ |
|
||||
var decoder; |
|
||||
export var Hex = { |
|
||||
decode: function (a) { |
|
||||
var i; |
|
||||
if (decoder === undefined) { |
|
||||
var hex = "0123456789ABCDEF"; |
|
||||
var ignore = " \f\n\r\t\u00A0\u2028\u2029"; |
|
||||
decoder = {}; |
|
||||
for (i = 0; i < 16; ++i) { |
|
||||
decoder[hex.charAt(i)] = i; |
|
||||
} |
|
||||
hex = hex.toLowerCase(); |
|
||||
for (i = 10; i < 16; ++i) { |
|
||||
decoder[hex.charAt(i)] = i; |
|
||||
} |
|
||||
for (i = 0; i < ignore.length; ++i) { |
|
||||
decoder[ignore.charAt(i)] = -1; |
|
||||
} |
|
||||
} |
|
||||
var out = []; |
|
||||
var bits = 0; |
|
||||
var char_count = 0; |
|
||||
for (i = 0; i < a.length; ++i) { |
|
||||
var c = a.charAt(i); |
|
||||
if (c == "=") { |
|
||||
break; |
|
||||
} |
|
||||
c = decoder[c]; |
|
||||
if (c == -1) { |
|
||||
continue; |
|
||||
} |
|
||||
if (c === undefined) { |
|
||||
throw new Error("Illegal character at offset " + i); |
|
||||
} |
|
||||
bits |= c; |
|
||||
if (++char_count >= 2) { |
|
||||
out[out.length] = bits; |
|
||||
bits = 0; |
|
||||
char_count = 0; |
|
||||
} |
|
||||
else { |
|
||||
bits <<= 4; |
|
||||
} |
|
||||
} |
|
||||
if (char_count) { |
|
||||
throw new Error("Hex encoding incomplete: 4 bits missing"); |
|
||||
} |
|
||||
return out; |
|
||||
} |
|
||||
}; |
|
@ -1,9 +0,0 @@ |
|||||
export declare class Int10 { |
|
||||
constructor(value?: string | number); |
|
||||
mulAdd(m: number, c: number): void; |
|
||||
sub(c: number): void; |
|
||||
toString(base?: number): string; |
|
||||
valueOf(): number; |
|
||||
simplify(): number | this; |
|
||||
private buf; |
|
||||
} |
|
@ -1,87 +0,0 @@ |
|||||
// Big integer base-10 printing library
|
|
||||
// Copyright (c) 2014 Lapo Luchini <lapo@lapo.it>
|
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
|
||||
// copyright notice and this permission notice appear in all copies.
|
|
||||
//
|
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||
/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */ |
|
||||
var max = 10000000000000; // biggest integer that can still fit 2^53 when multiplied by 256
|
|
||||
var Int10 = /** @class */ (function () { |
|
||||
function Int10(value) { |
|
||||
this.buf = [+value || 0]; |
|
||||
} |
|
||||
Int10.prototype.mulAdd = function (m, c) { |
|
||||
// assert(m <= 256)
|
|
||||
var b = this.buf; |
|
||||
var l = b.length; |
|
||||
var i; |
|
||||
var t; |
|
||||
for (i = 0; i < l; ++i) { |
|
||||
t = b[i] * m + c; |
|
||||
if (t < max) { |
|
||||
c = 0; |
|
||||
} |
|
||||
else { |
|
||||
c = 0 | (t / max); |
|
||||
t -= c * max; |
|
||||
} |
|
||||
b[i] = t; |
|
||||
} |
|
||||
if (c > 0) { |
|
||||
b[i] = c; |
|
||||
} |
|
||||
}; |
|
||||
Int10.prototype.sub = function (c) { |
|
||||
// assert(m <= 256)
|
|
||||
var b = this.buf; |
|
||||
var l = b.length; |
|
||||
var i; |
|
||||
var t; |
|
||||
for (i = 0; i < l; ++i) { |
|
||||
t = b[i] - c; |
|
||||
if (t < 0) { |
|
||||
t += max; |
|
||||
c = 1; |
|
||||
} |
|
||||
else { |
|
||||
c = 0; |
|
||||
} |
|
||||
b[i] = t; |
|
||||
} |
|
||||
while (b[b.length - 1] === 0) { |
|
||||
b.pop(); |
|
||||
} |
|
||||
}; |
|
||||
Int10.prototype.toString = function (base) { |
|
||||
if ((base || 10) != 10) { |
|
||||
throw new Error("only base 10 is supported"); |
|
||||
} |
|
||||
var b = this.buf; |
|
||||
var s = b[b.length - 1].toString(); |
|
||||
for (var i = b.length - 2; i >= 0; --i) { |
|
||||
s += (max + b[i]).toString().substring(1); |
|
||||
} |
|
||||
return s; |
|
||||
}; |
|
||||
Int10.prototype.valueOf = function () { |
|
||||
var b = this.buf; |
|
||||
var v = 0; |
|
||||
for (var i = b.length - 1; i >= 0; --i) { |
|
||||
v = v * max + b[i]; |
|
||||
} |
|
||||
return v; |
|
||||
}; |
|
||||
Int10.prototype.simplify = function () { |
|
||||
var b = this.buf; |
|
||||
return (b.length == 1) ? b[0] : this; |
|
||||
}; |
|
||||
return Int10; |
|
||||
}()); |
|
||||
export { Int10 }; |
|
After Width: | Height: | Size: 346 KiB |
@ -0,0 +1,108 @@ |
|||||
|
// subpages/OCRCard/pages/index/index.js
|
||||
|
const app = getApp() |
||||
|
import {getResidentBaseInfo} from "../../../../utils/api" |
||||
|
Page({ |
||||
|
|
||||
|
/** |
||||
|
* 页面的初始数据 |
||||
|
*/ |
||||
|
data: { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面加载 |
||||
|
*/ |
||||
|
onLoad(options) { |
||||
|
this.setData({ |
||||
|
statusHeight: app.globalData.deviceInfo.statusHeight, |
||||
|
navigationHeight: app.globalData.deviceInfo.navigationHeight, |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面初次渲染完成 |
||||
|
*/ |
||||
|
onReady() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面显示 |
||||
|
*/ |
||||
|
onShow() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面隐藏 |
||||
|
*/ |
||||
|
onHide() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 生命周期函数--监听页面卸载 |
||||
|
*/ |
||||
|
onUnload() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 页面相关事件处理函数--监听用户下拉动作 |
||||
|
*/ |
||||
|
onPullDownRefresh() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 页面上拉触底事件的处理函数 |
||||
|
*/ |
||||
|
onReachBottom() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 用户点击右上角分享 |
||||
|
*/ |
||||
|
onShareAppMessage() { |
||||
|
|
||||
|
}, |
||||
|
getTable: async function (type){ |
||||
|
|
||||
|
let parm ={ |
||||
|
searchKey:this.data.keyWord, |
||||
|
pageSize:10, |
||||
|
pageNo:1 |
||||
|
} |
||||
|
let {data,code,msg} = await getResidentBaseInfo(parm) |
||||
|
if(code == 0){ |
||||
|
this.setData({ |
||||
|
tableData: this.data.tableData.concat(data.list), |
||||
|
}) |
||||
|
}else{ |
||||
|
|
||||
|
} |
||||
|
}, |
||||
|
cardSuccess: async function(e){ |
||||
|
this.setData({ |
||||
|
keyWord:e.detail.id.text, |
||||
|
tableData:[] |
||||
|
}) |
||||
|
await this.getTable('card') |
||||
|
if(this.data.tableData.length != 0){ |
||||
|
wx.navigateTo({ |
||||
|
url: `/subpages/addResi/pages/addResi/addResi?type=edit&resiId=${this.data.tableData[0].resiId}`, |
||||
|
}) |
||||
|
}else{ |
||||
|
wx.navigateTo({ |
||||
|
url: `/subpages/addResi/pages/addResi/addResi?type=add`, |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
back(){ |
||||
|
wx.navigateBack({ |
||||
|
delta: 1 |
||||
|
}) |
||||
|
} |
||||
|
}) |
@ -0,0 +1,7 @@ |
|||||
|
{ |
||||
|
"usingComponents": { |
||||
|
"ocr-navigator": "plugin://ocr-plugin/ocr-navigator" |
||||
|
}, |
||||
|
"navigationStyle": "custom" |
||||
|
|
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
<!--subpages/OCRCard/pages/index/index.wxml--> |
||||
|
<view class="header"> |
||||
|
<image class="header-bg" src="../../image/headerBg.png" mode="widthFix" /> |
||||
|
<image src="../../../../images/back.png" class="back" bind:tap="back" style=" top: {{statusHeight}}px;width: 50rpx;height: 50rpx;" bindtap="back" mode=""/> |
||||
|
<view class="navigation" style="height: {{navigationHeight}}px; top: {{statusHeight}}px;"> |
||||
|
身份证识别 |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="body"> |
||||
|
<image src="../../../../images/card.png" mode=""/> |
||||
|
<view> |
||||
|
<b>身份识别:</b>是在居民出示身份证原件或图片的场合下,通过OCR技术拍摄识别身份证信息。 |
||||
|
</view> |
||||
|
<ocr-navigator bind:onSuccess="cardSuccess" certificateType="idCard" opposite="{{false}}" class="ocr"> |
||||
|
<button hover-class="color">开始识别</button> |
||||
|
</ocr-navigator> |
||||
|
</view> |
@ -0,0 +1,82 @@ |
|||||
|
/* subpages/OCRCard/pages/index/index.wxss */ |
||||
|
page { |
||||
|
width: 100%; |
||||
|
min-height: 100vh; |
||||
|
overflow-y: scroll; |
||||
|
background-color: #f7f7f7; |
||||
|
} |
||||
|
.top20{ |
||||
|
margin-top: 20rpx; |
||||
|
} |
||||
|
.header { |
||||
|
width: 100%; |
||||
|
height: 550rpx; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
.blue{ |
||||
|
color: #3A80E7 ; |
||||
|
} |
||||
|
.red{ |
||||
|
color: #FF502E; |
||||
|
} |
||||
|
.header .header-bg { |
||||
|
width: 100%; |
||||
|
height: 444rpx; |
||||
|
position: absolute; |
||||
|
height: 100%; |
||||
|
z-index: -997; |
||||
|
} |
||||
|
.header .navigation { |
||||
|
width: 100%; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
color: #333333; |
||||
|
font-size: 32rpx; |
||||
|
position: relative; |
||||
|
z-index: 100; |
||||
|
} |
||||
|
.gray{ |
||||
|
color:#999 ; |
||||
|
font-size: 28rpx; |
||||
|
} |
||||
|
.font32{ |
||||
|
font-size: 32rpx; |
||||
|
} |
||||
|
.back{ |
||||
|
width: 30rpx; |
||||
|
height: 30rpx; |
||||
|
margin-left: 20rpx; |
||||
|
position: absolute; |
||||
|
margin-top: 20rpx; |
||||
|
border-radius: 0rpx; |
||||
|
z-index: 101; |
||||
|
} |
||||
|
|
||||
|
.body{ |
||||
|
position: relative; |
||||
|
top: -400rpx; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
padding: 0 70rpx; |
||||
|
align-items: center; |
||||
|
} |
||||
|
button{ |
||||
|
height: 84rpx; |
||||
|
line-height: 84rpx; |
||||
|
width: 100% !important; |
||||
|
padding: 0; |
||||
|
text-align: center; |
||||
|
color: #fff; |
||||
|
font-size: 33rpx; |
||||
|
border-radius: 84rpx; |
||||
|
background: linear-gradient(to right, #82b4fd, #3e93fe); |
||||
|
margin: 160rpx 0 0!important; |
||||
|
} |
||||
|
.ocr{ |
||||
|
width: 100%; |
||||
|
} |
||||
|
.color{ |
||||
|
color: #fff; |
||||
|
} |
Before Width: | Height: | Size: 359 KiB After Width: | Height: | Size: 184 KiB |
Before Width: | Height: | Size: 359 KiB After Width: | Height: | Size: 184 KiB |
@ -1,7 +1,8 @@ |
|||||
{ |
{ |
||||
"usingComponents": { |
"usingComponents": { |
||||
"load-more": "../../../../../components/loadMore/loadMore", |
"load-more": "../../../../../components/loadMore/loadMore", |
||||
"no-data": "../../../../../components/noData/nodata" |
"no-data": "../../../../../components/noData/nodata", |
||||
|
"ocr-navigator": "plugin://ocr-plugin/ocr-navigator" |
||||
}, |
}, |
||||
"navigationBarTitleText": "选择居民" |
"navigationBarTitleText": "选择居民" |
||||
} |
} |