utf8 加密與解密

LeoYao發表於2019-11-29
function UTF8Encoder(options) {
        var fatal = options.fatal;
        this.encode = function(output_byte_stream, code_point_pointer) {
            var code_point = code_point_pointer.get();
            if (code_point === EOF_code_point) {
                return EOF_byte;
            }
            code_point_pointer.offset(1);
            if (inRange(code_point, 0xD800, 0xDFFF)) {
                return encoderError(code_point);
            }
            if (inRange(code_point, 0x0000, 0x007f)) {
                return output_byte_stream.emit(code_point);
            }
            var count, offset;
            if (inRange(code_point, 0x0080, 0x07FF)) {
                count = 1;
                offset = 0xC0;
            } else if (inRange(code_point, 0x0800, 0xFFFF)) {
                count = 2;
                offset = 0xE0;
            } else if (inRange(code_point, 0x10000, 0x10FFFF)) {
                count = 3;
                offset = 0xF0;
            }
            var result = output_byte_stream.emit(div(code_point, Math.pow(64, count)) + offset);
            while (count > 0) {
                var temp = div(code_point, Math.pow(64, count - 1));
                result = output_byte_stream.emit(0x80 + (temp % 64));
                count -= 1;
            }
            return result;
        }
        ;
    }
function UTF8Decoder(options) {
        var fatal = options.fatal;
        var utf8_code_point = 0
          , utf8_bytes_needed = 0
          , utf8_bytes_seen = 0
          , utf8_lower_boundary = 0;
        this.decode = function(byte_pointer) {
            var bite = byte_pointer.get();
            if (bite === EOF_byte) {
                if (utf8_bytes_needed !== 0) {
                    return decoderError(fatal);
                }
                return EOF_code_point;
            }
            byte_pointer.offset(1);
            if (utf8_bytes_needed === 0) {
                if (inRange(bite, 0x00, 0x7F)) {
                    return bite;
                }
                if (inRange(bite, 0xC2, 0xDF)) {
                    utf8_bytes_needed = 1;
                    utf8_lower_boundary = 0x80;
                    utf8_code_point = bite - 0xC0;
                } else if (inRange(bite, 0xE0, 0xEF)) {
                    utf8_bytes_needed = 2;
                    utf8_lower_boundary = 0x800;
                    utf8_code_point = bite - 0xE0;
                } else if (inRange(bite, 0xF0, 0xF4)) {
                    utf8_bytes_needed = 3;
                    utf8_lower_boundary = 0x10000;
                    utf8_code_point = bite - 0xF0;
                } else {
                    return decoderError(fatal);
                }
                utf8_code_point = utf8_code_point * Math.pow(64, utf8_bytes_needed);
                return null;
            }
            if (!inRange(bite, 0x80, 0xBF)) {
                utf8_code_point = 0;
                utf8_bytes_needed = 0;
                utf8_bytes_seen = 0;
                utf8_lower_boundary = 0;
                byte_pointer.offset(-1);
                return decoderError(fatal);
            }
            utf8_bytes_seen += 1;
            utf8_code_point = utf8_code_point + (bite - 0x80) * Math.pow(64, utf8_bytes_needed - utf8_bytes_seen);
            if (utf8_bytes_seen !== utf8_bytes_needed) {
                return null;
            }
            var code_point = utf8_code_point;
            var lower_boundary = utf8_lower_boundary;
            utf8_code_point = 0;
            utf8_bytes_needed = 0;
            utf8_bytes_seen = 0;
            utf8_lower_boundary = 0;
            if (inRange(code_point, lower_boundary, 0x10FFFF) && !inRange(code_point, 0xD800, 0xDFFF)) {
                return code_point;
            }
            return decoderError(fatal);
        }
        ;
    }

相關文章