- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
更新代码
我正在使用此代码声明使用串行 2-USB 设备。它出现了,我可以查询有关它的信息,即。 “连接到USB2.0-Serial VID:6790 PID:29987”(秦恒的CH34x)。需要明确的是,我使用了 winUSB 驱动程序(使用 zadig-2.5.exe 下载,Windows 10)并卸载了原始驱动程序。
我将接收到的数据作为数据 View 获取,但是当我进行解码时,它会出现乱码。而且我看到数组长度几乎对应于我知道我的 ESP8266 通过串行端口发布的内容。
解码数据示例:�(#���D"D�T�b�!A#7mP�R�N����#�m93aw9 ½�d-K��b��BF+3ѡ��kag1�R�#��#!!r����g�!d��a��谛oa��399�}��1D�#��'99�����9�����'99���'99����@@譛
我以 Uint8Arrays 的形式获取数据,但即使我尝试使自己的解析器产生相同的乱码,最终结果也是如此。我是否需要像开始位、确认位等那样关心 USB 的东西?那里的所有示例代码只是做一个文本解码器,仅此而已。
serial.js + index.html
//https://zadig.akeo.ie/ --- for windows, get supported driver "winusb"
//https://www.cypress.com/file/134171/download --- read up on the USB standard
//https://cscott.net/usb_dev/data/devclass/usbcdc11.pdf --- more here
//http://www.linux-usb.org/usb.ids --- list of ids
//https://developer.mozilla.org/en-US/docs/Web/API/USBDevice --- more info
// host --- data pipe ---> vendor/device TX (host) transmitting data
// host <-- control pipe --> vendor/device Endpoint 0 (this is the one we us to control data up (from device to host) and data down (from host to device)
// host <-- data pipe ---- vendor/device RX (host) receiving data
//It's possible to send interrupt, bulk ant isochronus data packages.... this flasher only use bulk (and control transfers on the control pipe)
//Typically the usb cable work/look as follows:
//red 5V, black 0V/GND, green TX(host), white RX(host)
//USB standard transaction:
// [TOKEN][DATA][HANDSHAKE]
//... the data package ....
//1: Packet ID (PID): 8 bits (4 type bits + 4 error check bits) this is where we till if the transfer is "in / out / setup / SOF (start of frame)
//2: Optional device address: 7 bits (max 127 devices in the bus)
//3: Optional endpoint address: 4 bits (max 16 endpoints in a device)
//4: Optional payload data (0 ... 1023 bytes)
//5: Optional CRC (cyclic redundancy checksum)
//this flasher uses 8-N-1 for the serial parameters (8 data bits, No parity and 1 stop bit)
//when we control the "device" we control the USB chip directly, when we control the "interface" we control the serial functionality (class: 0xFF, vendor specific driver)
window.addEventListener("load", initiate, false);
//The different hardware we support + their specific data/configs
const table = {
0x0403: {"FTDI": {
0x6001: "FT232R",
0x6010: "FT2232H",
0x6011: "FT4232H",
0x6014: "FT232H",
0x6015: "FT231X", // same ID for FT230X, FT231X, FT234XD
}},
0x1a86: {"Quinheng": {
0x7523: "CH340",
0x5523: "CH341A",
}},
0x10c4: {"Silicon Labs": {
0xea60: "CP210x", // same ID for CP2101, CP2103, CP2104, CP2109
0xea70: "CP2105",
0xea71: "CP2108",
}},
0x067b: {"Prolific": {
0x2303: "PL2303"
}}
}
const config = {
"DEBUG" : true,
"DEFAULT_BAUD_RATE" : 115200,
//CH34x --> https://github.com/torvalds/linux/blob/master/drivers/usb/serial/ch341.c <-- we have used the linux driver and made into a webUSB driver
"CH340": {
"BAUD_RATES" : [600,1200,2400,4800,9600,14400,19200,38400,57600,76800,115200,230400], // highest is 300 0000 limited by the BAUD_RATE_MAX_BPS
"REQUEST_READ_VERSION" : 0x5F,
"REQUEST_READ_REGISTRY" : 0x95,
"REQUEST_WRITE_REGISTRY" : 0x9A,
"REQUEST_SERIAL_INITIATION" : 0xA1,
"REG_DIVISOR" : 0x13,
"REG_PRESCALER" : 0x12,
"REG_LCR_1" : 0x18,
"REG_LCR_2" : 0x25,
"REG_MODEM_CTRL" : 0xA4,
"REG_MODEM_VALUE_OFF" : 0xFF,
"REG_MODEM_VALUE_ON" : 0xDF,
"REG_MODEM_VALUE_CALL" : 0x9F, // what does it do??
//"BAUD_RATE_CHIP_CLOCK_FREQ" : 48000000, // which one is it? 12MHz is the official value for the 340...
"BAUD_RATE_CHIP_CLOCK_FREQ" : 12000000,
"BAUD_RATE_MAX_DIVISOR" : function (ps, fact) {
return (1 << (12 - 3 * (ps) - (fact)))
},
"BAUD_RATE_MIN" : function (ps) {
return (config.CH340.BAUD_RATE_CHIP_CLOCK_FREQ / (config.CH340.BAUD_RATE_MAX_DIVISOR(ps, 1) * 512))
},
"BAUD_RATE_MIN_BPS" : function () { // 47 bps
return Math.ceil((config.CH340.BAUD_RATE_CHIP_CLOCK_FREQ + (config.CH340.BAUD_RATE_MAX_DIVISOR(0, 0) * 256) - 1) / (config.CH340.BAUD_RATE_MAX_DIVISOR(0, 0) * 256)); //Linux DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
},
"BAUD_RATE_MAX_BPS" : function () { // 3000000 bps
return Math.floor(config.CH340.BAUD_RATE_CHIP_CLOCK_FREQ / (config.CH340.BAUD_RATE_MAX_DIVISOR(3, 0) * 2));
},
"QUIRK_LIMITED_PRESCALER" : 0b0, //binary 0
"QUIRK_SIMULATE_BREAK" : 0b1, //binary 1
"QUIRKS" : 0,
"LCR_ENABLE_RX" : 0x80,
"LCR_ENABLE_TX" : 0x40,
"LCR_DATA_BITS_8N1" : 0x03,
"LCR" : function () {
return config.CH340.LCR_ENABLE_RX | config.CH340.LCR_ENABLE_TX | config.CH340.LCR_DATA_BITS_8N1;
},
"FLAG_DTR" : false,
"FLAG_RTS" : false,
"REG_MCR_DTR" : 0x20,
"REG_MCR_RTS" : 0x40,
"MCR" : function () {
return (config.CH340.FLAG_RTS ? config.CH340.REG_MCR_RTS : 0) | (config.CH340.FLAG_DTR ? config.CH340.REG_MCR_DTR : 0); // if false, set to 0, else set to value of the REG_MCR_<...>
},
}
}
const serial = {};
let device = {};
let port;
(function() {
'use strict';
serial.getPorts = function() {
return navigator.usb.getDevices().then(devices => {
return devices.map(device => new serial.Port(device));
});
};
serial.requestPort = function() {
let supportedHardware = [];
//This one create the filter of hardware based on the hardware table
Object.keys(table).map(vendorId => {
Object.keys(table[vendorId]).map(vendorName => {
Object.keys(table[vendorId][vendorName]).map(productId => {
supportedHardware.push({
"vendorId": vendorId,
"productId": productId
})
})
})});
//device contains the "device descriptor" (see USB standard), add as a new device to be able to control
return navigator.usb.requestDevice({ 'filters': supportedHardware }).then(
device => new serial.Port(device)
);
}
//set it to the active device..
serial.Port = function(device) {
this.device_ = device;
};
//here's the config + read loop is taking place....
serial.Port.prototype.connect = function() {
//this is the read loop on whatever port is currently used... it will repeat itself
let readLoop = () => {
this.device_.transferIn(this.endpointIn_, 64).then(result => {
this.onReceive(result.data);
readLoop();
}, error => {
this.onReceiveError(error);
});
};
return this.device_.open()
.then(() => {
//first we get some GUI stuff populated, we use "device" for that... serial and port are used for the configuration elsewhere
device.hostName = port.device_.productName;
device.vendorName = Object.keys(table[port.device_.vendorId])[0];
device.chip = table[port.device_.vendorId][device.vendorName][port.device_.productId];
device.serialNumber = port.device_.serialNumber;
device.manufacturerName = port.device_.manufacturerName;
//1: we set an configuration (configuration descriptor in the USB standard)
if (this.device_.configuration === null) {
return this.device_.selectConfiguration(1);
}
})
.then(() => {
//2: we set what endpoints for data we will use, we use only "bulk" transfer and thus we parse their addresses
let configInterfaces = this.device_.configuration.interfaces;
configInterfaces.forEach(element => {
element.alternates.forEach(elementalt => {
if (elementalt.interfaceClass === 0xff) {
this.interfaceNumber_ = element.interfaceNumber;
elementalt.endpoints.forEach(elementendpoint => {
//This part here get the bulk in and out endpoints programmatically
if (elementendpoint.direction === "out" && elementendpoint.type === "bulk") {
this.endpointOut_ = elementendpoint.endpointNumber;
this.endpointOutPacketSize_ = elementendpoint.packetSize;
}
if (elementendpoint.direction === "in" && elementendpoint.type === "bulk") {
this.endpointIn_ = elementendpoint.endpointNumber;
this.endpointInPacketSize_ = elementendpoint.packetSize;
}
})
}
})
})
})
//3: we claim this interface and select the alternative interface
.then(() => this.device_.claimInterface(this.interfaceNumber_))
.then(() => this.device_.selectAlternateInterface(this.interfaceNumber_, 0))
//4: we configure in and out transmissions, based on detected hardware
.then(() => serial[device.chip](this))
//5: we start the loop
.then(() => {
//console.log(this);
readLoop();
})
};
//upon disconnect, what to do
serial.Port.prototype.disconnect = async function() {
await serial[device.chip](this).DISCONNECT;
};
//send data, what to do
serial.Port.prototype.send = function(data) {
return this.device_.transferOut(this.endpointOut_, data);
};
serial.controlledTransfer = async function (object, direction, type, recipient, request, value = 0, data = new DataView(new ArrayBuffer(0)), index = object.interfaceNumber_) {
direction = direction.charAt(0).toUpperCase() + direction.slice(1);
type = type.toLowerCase();
recipient = recipient.toLowerCase();
if (data.byteLength === 0 && direction === "In") {
// we set how many bits we want back for an "in"
// so set data = 0....N in the call otherwise it will default to 0
data = 0;
}
return await object.device_["controlTransfer" + direction]({
'requestType': type,
'recipient': recipient,
'request': request,
'value': value,
'index': index
}, data)
.then(res => {
if (config.DEBUG) {
//debugger; // remove comment for extra debugging tools
console.log(res);
}
if (res.status !== "ok") {
let errorRequest = `
controlTransfer` + direction + `
'requestType': ` + type + `,
'recipient': ` + recipient + `,
'request': 0x` + request.toString(16) + `,
'value': 0x` + value.toString(16) + `,
'index': 0x` + index.toString(16) + `
}`;
console.warn("error!", errorRequest, data) // add more here
}
if (res.data !== undefined && res.data.buffer !== undefined) {
return res.data.buffer;
}
return null;
});
};
// you can really use any numerical value since JS treat them the same:
// dec = 15 // dec will be set to 15
// bin = 0b1111; // bin will be set to 15
// oct = 0o17; // oct will be set to 15
// oxx = 017; // oxx will be set to 15
// hex = 0xF; // hex will be set to 15
// note: bB oO xX are all valid
serial.hexToDataView = function (number) {
if (number === 0) {
let array = new Uint8Array([0]);
return new DataView(array.buffer)
}
let hexString = number.toString(16);
// split the string into pairs of octets
let pairs = hexString.match(/[\dA-F]{2}/gi);
// convert the octets to integers
let integers = pairs.map(function(s) {
return parseInt(s, 16);
});
let array = new Uint8Array(integers);
return new DataView(array.buffer);
}
// you can give this method a string like "00 AA F2 01 23" and it will turn it into a DataView for the webUSB API transfer data
serial.hexStringArrayToDataView = function (hexString) {
// remove the leading 0x (if any)
hexString = hexString.replace(/^0x/, '');
// split the string into pairs of octets
let pairs = hexString.split(/ /);
// convert the octets to integers
let integers = pairs.map(function(s) {
return parseInt(s, 16);
});
let array = new Uint8Array(integers);
return new DataView(array.buffer);
}
// these are the hardware specific initialization procedures...
serial["CH340"] = async function (obj, baudRate = config.DEFAULT_BAUD_RATE) {
/*
direction request value
in 0xA1 0xC39C -
in 0x9A 0xF2C -
in 0xA4 0xDF - modem on? 0xFF modem off?
in 0xA4 0x9F - modem?
in 0x95 0x706 - got 2 bytes
in 0x9A 0x2727 - LCR wrong??
in 0x9A 0x1312 - baud rate seems ok
in 0x95 0x706 - got 2 bytes
in 0x9A 0x2727 -
*/
/* await serial.controlledTransfer(obj,"in", "vendor", "device", config.CH340.REQUEST_READ_REGISTRY, 0x706); //test
return;
await serial.controlledTransfer(obj,"out", "vendor", "device", config.CH340.REQUEST_SERIAL_INITIATION, 0xC39C); // test
await serial.controlledTransfer(obj,"in", "vendor", "device", config.CH340.REQUEST_WRITE_REGISTRY, 0xF2C); // test
await serial.controlledTransfer(obj,"in", "vendor", "device", config.CH340.REG_MODEM_CTRL, config.CH340.REG_MODEM_VALUE_ON); // test
await serial.controlledTransfer(obj,"in", "vendor", "device", config.CH340.REG_MODEM_CTRL, config.CH340.REG_MODEM_VALUE_CALL); // test
await serial.controlledTransfer(obj,"in", "vendor", "device", config.CH340.REQUEST_READ_REGISTRY, 0x706); //test
await serial.controlledTransfer(obj,"in", "vendor", "device", config.CH340.REQUEST_WRITE_REGISTRY, 0x2727); //test
await serial.controlledTransfer(obj,"in", "vendor", "device", config.CH340.REQUEST_WRITE_REGISTRY, 0x1312); //test
await serial.controlledTransfer(obj,"in", "vendor", "device", config.CH340.REQUEST_READ_REGISTRY, 0x706); //test
await serial.controlledTransfer(obj,"in", "vendor", "device", config.CH340.REQUEST_WRITE_REGISTRY, 0x2727); //test
*/
await serial.controlledTransfer(obj,"in", "vendor", "device", config.CH340.REQUEST_READ_VERSION); // we expect to get a OK with the response of [48, 00] 0x30 0x00 or 0x27 0x00.... you can look at the response by adding a "let r = await serial.controlledTrans....." and then console log the "r"
//return; // if I uncomment this and thus not gonna continue the script I get gibbrish.... but as far as I can tell I have followed the linux initialization ?
await serial.controlledTransfer(obj,"out", "vendor", "device", config.CH340.REQUEST_SERIAL_INITIATION);
await serial["CH340"].setBaudRate(obj, baudRate);
await serial.controlledTransfer(obj,"out", "vendor", "device", config.CH340.REG_MODEM_CTRL, config.CH340.MCR()); // handshake
// now what? all the control transfers came back "ok"?
}
serial["CH340"].setBaudRate = async function (obj, baudRate) {
let data = serial["CH340"].getDivisor(baudRate);
// CH34x buffers data until a full endpoint size packet (32 bytes) has been reached unless bit 7 is set
data |= (1 << 7); // data |= (1 << 6); //seems correct for the 7th bit??
data = serial.hexToDataView(data);
await serial.controlledTransfer(obj,"out", "vendor", "device", config.CH340.REQUEST_WRITE_REGISTRY, (config.CH340.REG_DIVISOR << 8 | config.CH340.REG_PRESCALER), data);
data = serial.hexToDataView(config.CH340.LCR());
await serial.controlledTransfer(obj,"out", "vendor", "device", config.CH340.REQUEST_WRITE_REGISTRY, (config.CH340.REG_LCR_2 << 8 | config.CH340.REG_LCR_1), data);
}
serial["CH340"].getDivisor = function (baudRate) {
let forceFactor0 = false;
// make sure our baud rate is with the min max
let baudRateChecked = Math.min(Math.max(parseInt(baudRate), config.CH340.BAUD_RATE_MIN_BPS()), config.CH340.BAUD_RATE_MAX_BPS());
// start with highest possible base clock (factor = 1) that will give a divisor strictly less than 512.
let factor = 1;
let ps = 3;
for (ps; ps >= 0; ps--) {
if (baudRateChecked > config.CH340.BAUD_RATE_MIN(ps)) {
break;
}
}
// determine corresponding divisor, rounding down
let clockDivisor = Math.floor(config.CH340.BAUD_RATE_MAX_DIVISOR(ps, factor));
let divisor = config.CH340.BAUD_RATE_CHIP_CLOCK_FREQ / (clockDivisor * baudRateChecked);
// some devices require a lower base clock if ps < 3
if (ps < 3 && (config.CH340.QUIRKS & config.CH340.QUIRK_LIMITED_PRESCALER)) {
forceFactor0 = true;
}
// if we force a factor = 0 or have divisors outside range, split the base clock divisor by 2 and make factor=0
if (divisor < 9 || divisor > 255 || forceFactor0) {
divisor /= 2;
clockDivisor *= 2;
factor = 0;
}
divisor = Math.ceil(divisor);
// pick next divisor if resulting rate is closer to the requested one, scale up (16x) to avoid rounding errors on low rates.
let compare1 = 16 * config.CH340.BAUD_RATE_CHIP_CLOCK_FREQ / (clockDivisor * divisor) - 16 * baudRateChecked;
let compare2 = 16 * baudRateChecked - 16 * (config.CH340.BAUD_RATE_CHIP_CLOCK_FREQ / (clockDivisor * (divisor + 1)));
if (compare1 >= compare2) {
divisor++;
}
// prefer lower base clock (factor = 0) if even divisor "divisor % 2"... this makes the receiver more tolerant to errors
if (factor === 1 && (divisor % 2 === 0) ) {
divisor /= 2;
factor = 0;
}
return (0x100 - divisor) << 8 | factor << 2 | ps;
}
serial["CH340"].DISCONNECT = async function (obj) {
await serial.controlledTransfer(obj,"in", "vendor", "device", config.CH340.REG_MODEM_CTRL, config.CH340.REG_MODEM_VALUE_OFF);
}
serial["CP210x"] = async function (obj, baudRate = config.DEFAULT_BAUD_RATE) {
}
serial["CP2105"] = async function (obj, baudRate = config.DEFAULT_BAUD_RATE) {
}
serial["CP2108"] = async function (obj, baudRate = config.DEFAULT_BAUD_RATE) {
}
serial["PL2303"] = async function (obj, baudRate = config.DEFAULT_BAUD_RATE) {
}
serial["FT2232H"] = async function (obj, baudRate = config.DEFAULT_BAUD_RATE) {
}
serial["FT4232H"] = async function (obj, baudRate = config.DEFAULT_BAUD_RATE) {
}
serial["FT232H"] = async function (obj, baudRate = config.DEFAULT_BAUD_RATE) {
}
serial["FT231X"] = async function (obj, baudRate = config.DEFAULT_BAUD_RATE) {
}
})();
//GUI function "connect"
function connect() {
port.connect().then(() => {
document.getElementById('editor').value = "connected to: " + device.hostName + "\nvendor name: " + device.vendorName + "\nchip type: " + device.chip;
port.onReceive = data => {
console.log(data);
document.getElementById('output').value += new TextDecoder().decode(data);
}
port.onReceiveError = error => {
//console.error(error);
port.disconnect();
};
});
}
//GUI function "disconnect"
function disconnect() {
port.disconnect();
}
//GUI function "send"
function send(string) {
console.log("sending to serial:" + string.length);
if (string.length === 0)
return;
console.log("sending to serial: [" + string +"]\n");
let data = new TextEncoder('utf-8').encode(string);
console.log(data);
if (port) {
port.send(data);
}
}
//the init function which we have an event listener connected to
function initiate(){
serial.getPorts()
.then(ports => {
//these are devices already paired, let's try the first one...
if (ports.length > 0) {
port = ports[0];
connect();
}
});
document.querySelector("#connect").onclick = async function () {
await serial.requestPort().then(selectedPort => {
if (port === undefined || port.device_ !== selectedPort.device_) {
port = selectedPort;
connect();
} else {
// port already selected...
}
});
}
document.querySelector("#disconnect").onclick = function() {
disconnect()
}
document.querySelector("#submit").onclick = () => {
let source = document.querySelector("#editor").value;
send(source);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="serial.js"></script>
<title>Grovkillen test webusb</title>
</head>
<body>
<button id="connect">Connect</button>
<button id="disconnect">disConnect</button>
<label for="editor">TX</label><textarea id="editor">Flash Easy</textarea>
<button id="submit">Send</button>
<label for="output">RX</label><textarea id="output"></textarea>
</body>
最佳答案
这不是 WebUSB 的缺陷,而是您正在运行的脚本的缺陷。 Arduino 示例存储库中包含的 serial.js 脚本旨在与 Arduino 设备配合使用,这些设备不需要设置波特率,因为端口是虚拟的。为了在 USB 到串行适配器上设置波特率,您需要发送 SET_LINE_CODING 控制传输。这应该在现有代码中的 SET_CONTROL_LINE_STATE 命令之前。这里有控制传输结构的文档:
https://github.com/MarkDing/lufa-efm32#311-set-line-coding
关于javascript - webUSB api 工作但接收到的数据未正确解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64929987/
我有以下 json: {"results": [{"columns":["room_id","player_name","player_ip"], "types":["integer","text
我在 go 中获取格式不一致的 JSON 文件。例如,我可以有以下内容: {"email": "\"blah.blah@blah.com\""} {"email": "robert@gmail.com
JavaScript中有JSON编码/解码base64编码/解码函数吗? 最佳答案 是的,btoa() 和 atob() 在某些浏览器中可以工作: var enc = btoa("this is so
我在其中一个项目中使用了 Encog,但在解码 One-Of Class 时卡住了。该字段的规范化操作之一是 NormalizationAction.OneOf,它具有三个输出。当我评估时,我想解码预
在我的 previous question关于使用 serialize() 创建对象的 CSV 我从 jmoy 那里得到了一个很好的答案,他推荐了我的序列化文本的 base64 编码。这正是我要找的。
有些事情让我感到困惑 - 为什么 this image在每个浏览器中显示不同? IE9(和 Windows 照片查看器)中的图像: Firefox(和 Photoshop)中的图像: Chrome(和
是否可以在不知道它的类型( JAXBContext.newInstance(clazz) )的情况下解码一个类,或者什么是测试即将到来的正确方法? 我确实收到了从纯文本中解码的消息 - 字符串 传入的
我正在尝试使用 openSSL 库进行 Base64 解码,然后使用 CMS 来验证签名。 下面的代码总是将缓冲区打印为 NULL。 char signed_data[] = "MIIO"; int
我有一个带有 SEL 类型实例变量的类,它是对选择器的引用。在encodeWithCoder/initWithCoder中,如何编码/解码这种类型的变量? 最佳答案 您可以使用 NSStringFro
var url = 'http://www.googleapis.com/customsearch/v1?q=foo&searchType=image'; window.fetch(url) .t
我想知道Android 2.2、2.3和3,4支持的音频/视频格式列表。我也想知道哪些Android版本支持视频编码和解码。我经历了this link,但是关于编码和解码我并不清楚。 任何人的回答都是
我在其中一个项目中使用 Encog,但在解码 One-Of 类时遇到了困难。该字段的规范化操作之一是 NormalizationAction.OneOf,它具有三个输出。当我评估时,我想解码预测值。如
我正在尝试解码现有的 xml 文件,以便我可以正确处理数据,但 XML 结构看起来很奇怪。下面是 xml 示例以及我创建的对象。 11 266 AA1001 1
对 unicode 字符进行 URL 编码的常用方法是将其拆分为 2 %HH 代码。 (\u4161 => %41%61) 但是,unicode在解码时是如何区分的呢?您如何知道 %41%61 是 \
我正在尝试将 json 字符串解码为 Map。 我知道有很多这样的问题,但我需要非常具体的格式。例如,我有 json 字符串: { "map": { "a": "b",
我有一个查询,我认为需要像这样(解码会更大) SELECT firstName, lastName, decode(mathMrk, 80, 'A', mathMrk) as decodeMat
我知道PHP函数encode()和decode(),它们对我来说工作得很好,但我想在url中传递编码字符串,但encode确实返回特殊字符,如“=”、“”' “等等...... 这显然会破坏我的脚本,
我必须解码 Basic bW9uTG9naW46bW9uTW90RGVQYXNz 形式的 http 请求的授权 header 当我解码它时online ,我得到了正确的结果 monLogin:monM
这个问题已经有答案了: Decode Base64 data in Java (21 个回答) 已关闭 8 年前。 我想知道使用哪个库进行 Base64 编码/解码?我需要此功能足够稳定以供生产使用。
我正在尝试从 Arduino BT 解码 []byte,我的连接完美,问题是当我尝试解码数组时。我得到的只是这个字符�(发送的字节数相同)我认为问题出在解码上。我尝试使用 ASCII 字符集,但仍然存
我是一名优秀的程序员,十分优秀!