Skip to content

Instantly share code, notes, and snippets.

@Kielan
Last active September 6, 2025 20:45
Show Gist options
  • Save Kielan/92dd4676a26d9e853c53d0110d277909 to your computer and use it in GitHub Desktop.
Save Kielan/92dd4676a26d9e853c53d0110d277909 to your computer and use it in GitHub Desktop.
To convert a binary string into its corresponding character(s) in JavaScript, the following steps can be taken:
Split the binary string: If the binary string represents multiple characters (e.g., "01000001 01100010" for "Ab"), it needs to be split into individual binary representations of each character. This is typically done by splitting the string by a delimiter, usually a space.
const binaryString = "01000001 01100010"; // Binary for "Ab"
const binaryArray = binaryString.split(" ");
// binaryArray will be ["01000001", "01100010"]
Convert each binary segment to its decimal (ASCII/Unicode) equivalent: Each binary segment (representing a single character) needs to be converted into its decimal integer value. The parseInt() function with a radix of 2 is used for this purpose.
const decimalValue = parseInt("01000001", 2);
// decimalValue will be 65 (ASCII for 'A')
Convert the decimal value to its character representation: The String.fromCharCode() method is used to convert the decimal (ASCII or Unicode) value into its corresponding character.
const character = String.fromCharCode(65);
// character will be 'A'
Combine the characters: If multiple characters are being converted, the individual characters can be joined together to form a complete string.
const resultString = binaryArray.map(binary => String.fromCharCode(parseInt(binary, 2))).join("");
// resultString will be "Ab"
Example Function:
JavaScript
function binaryToText(binaryString) {
// Split the binary string into an array of individual binary character representations
const binaryArray = binaryString.split(" ");
// Map each binary string to its corresponding character
const characters = binaryArray.map(binary => {
// Convert the binary string to an integer (base 2)
const decimalValue = parseInt(binary, 2);
// Convert the integer to its corresponding character
return String.fromCharCode(decimalValue);
});
// Join the array of characters back into a single string
return characters.join("");
}
const binaryInput = "01001000 01100101 01101100 01101100 01101111"; // "Hello"
const convertedText = binaryToText(binaryInput);
console.log(convertedText); // Output: Hello
<!DOCTYPE html>
<!--
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
MSFT IE 11.0.9600 says:
Invalid HTML5 DOCTYPE. Consider using the interoperable form "<!DOCTYPE html>".
-->
<html>
<head>
<title>ARM1 Gate-level Simulation</title>
<style>
div.ms {
background-color:white;
font-family:monospace;
font-size:medium;
margin-left:10px;
padding-top:10px;
padding-bottom:10px;
}
</style>
<!-- <script type="text/javascript" src="macros.js"></script> -->
<!-- <script type="text/javascript" src="chipsim.js"></script> -->
<script type="text/javascript">
//Macros
function readNodeValueAsString(n){
if (typeof nodes[n] == 'undefined')
return 'x';
var v=nodes[n].state;
if ((typeof v == 'undefined') || (v==-1))
return 'x';
return v?'1':'0'
}
//FFDEFS
var ffdefs = [
6819,6820,
5992,6020,
1138,1177,
944,982,
];
//TRANSDEFS
var transdefs = [
10001,2,0,0,0,
10001,3,0,0,0,
10001,8371,0,0,0,
10001,8372,0,0,0,
];
//NODENAMES
var nodenames = {
0: 'vss',
1: 'vdd',
2: 'phi1_pad',
3: 'phi2_pad',
4: 'aen_internal',
5: 'ale',
};
//Chipsim
var nodes = new Array(), transistors = new Array();
var nvss=0, nvdd=1;
var ctrace = false;
var traceTheseNodes = [];
var traceTheseTransistors = [];
var loglevel = 0;
var recalclist = new Array();
var recalcHash = new Array();
var group = new Array();
var pads = [];
function setupNodes(){
for (var i = 0; i < 8760; i++) {
nodes[i] = {num: i, state: -1, gates: [], c1c2s: [],
plotted: 0, touched:0, switched:0, flipFlop: false};
}
for(var i = 0; i < ffdefs.length; ++i) {
nodes[ffdefs[i]].flipFlop = true;
}
}
function setupTransistors(){
for(i=0;i<transdefs.length;i+=5){
var trans = {};
var num = i/5;
transistors[num] = trans;
trans.touched = 0;
trans.switched = 0;
trans.gate = Math.abs(transdefs[i]);
trans.num = num;
trans.active = (transdefs[i]>=0);
trans.x = transdefs[i+3];
trans.y = transdefs[i+4];
trans.c1 = transdefs[i+1];
nodes[trans.c1].c1c2s.push(trans);
trans.on = false;
switch(trans.gate){
// output pad
case 10000:{
pads[nodenames[trans.c1]] = trans;
break;}
// input pad
case 10001: {
trans.c2 = nvss;
pads[nodenames[trans.c1]] = trans;
trans.on = true;
break;}
// io pad
case 10002: {
trans.c2 = nvss;
pads[nodenames[trans.c1]] = trans;
break;}
// gate is vss
case 10003:{
trans.gate = nvss;
trans.c2 = transdefs[i+2];
nodes[trans.c2].c1c2s.push(trans);
if (!trans.active)
trans.on = true;
break;}
// gates is vdd
case 10004:{
trans.gate = nvdd;
trans.c2 = transdefs[i+2];
nodes[trans.c2].c1c2s.push(trans);
if (trans.active)
trans.on = true;
break;}
default: {
trans.c2 = transdefs[i+2];
nodes[trans.gate].gates.push(trans);
nodes[trans.c2].c1c2s.push(trans);
break;}
}
}
};
//GEOM
var gl;
var csp = {}; // chip state program
var stp = {}; // stipple program
var trianglesIb;
var linesIb;
var startLayer, numLayersToDraw;
function init() {
var canvas = document.getElementById("gl-canvas");
gl = WebGLUtils.setupWebGL(canvas);
if (!gl) {
alert("WebGL isn't available");
}
gl.viewport(0,0,canvas.width,canvas.height);
gl.clearColor(clearColor[0],clearColor[1],clearColor[2],clearColor[3]);
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.CULL_FACE);
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
csp.id = initShaders(gl, "vsh_chip_state", "fsh_chip_state");
var prg = csp;
var id = prg.id;
prg.va_position = gl.getAttribLocation(id, "va_position");
prg.va_texCoord0 = gl.getAttribLocation(id, "va_texCoord0");
prg.vu_mvp = gl.getUniformLocation(id, "vu_mvp");
prg.stateSamp = gl.getUniformLocation(id, "t_state");
prg.colorSamp = gl.getUniformLocation(id, "t_layerColors");
stp.id = initShaders(gl, "vsh_chip_state_stipple", "fsh_chip_state_stipple");
prg = stp;
id = prg.id;
prg.va_position = gl.getAttribLocation(id, "va_position");
prg.va_texCoord0 = gl.getAttribLocation(id, "va_texCoord0");
prg.vu_mvp = gl.getUniformLocation(id, "vu_mvp");
prg.stateSamp = gl.getUniformLocation(id, "t_state");
prg.colorSamp = gl.getUniformLocation(id, "t_layerColors");
prg.fu_stippleOffset = gl.getUniformLocation(id, "fu_stippleOffset");
prg.fu_stippleFac = gl.getUniformLocation(id, "fu_stippleFac");
if (urlHas("cdaColors")) {
useCdaColors = false;
toggleColor();
}
loadBinaryData();
}
function loadBinaryData() {
var urlDir = '/sim/'
//var layerFileNames = ['l0.bin', 'l1.bin', 'l2.bin', 'l3.bin',
// 'l4.bin', 'l5.bin', 'l6.bin', 'l7.bin'];
var layerFileNames = ['10.bin'];
for (var i = 0; i < layerFileNames.length; ++i) {
var urlStr = urlDir + layerFileNames[i];
layerReqs[i] = new Uint16Request(urlStr);
}
coordReqs.tdReq = new Uint16Request('/sim/' + 'td.bin');
//coordReqs.rlReq = new Uint16Request('/sim/' + 'rl.bin');
//coordReqs.rwReq = new Uint16Request('/sim/' + 'rw.bin');
//coordReqs.rhReq = new Uint16Request('/sim/' + 'rh.bin');
//coordReqs.rtReq = new Uint16Request('/sim/' + 'rt.bin');
//coordReqs.llReq = new Uint16Request('/sim/' + 'll.bin');
//coordReqs.ilReq = new Uint32Request('/sim/' + 'il.bin');
//coordReqs.neReq = new Uint32Request('/sim/' + 'ne.bin');
coordReqArray = [coordReqs.tdReq];
}
function prepRender() {
}
function render() {
if (gl == null || gl == undefined) {
init();
}
if (!loaded) {
var coordReqDoneCount = 0;
for (var i = 0; i < coordReqArray.length; ++i) {
if (coordReqArray[i].success) {
++coordReqDoneCount;
}
}
var layerDoneCount = 0;
for (var i = 0; i < layerReqs.length; ++i) {
if (layerReqs[i].success) {
++layerDoneCount;
}
}
if (layerDoneCount == layerReqs.length &&
layerReqs.length > 0 && // thank you MSFT IE
coordReqDoneCount == coordReqArray.length) {
loaded = true;
// Make array of start locations
// ll.bin is list of index list lengths for each pattern
// il.bin is all index lists packed together. Each value is the
// 32-bit index of a rectangle.
//
var ll = coordReqs.llReq.u16Array;
raStart = new Uint32Array(ll.length);
var pos = 0;
var lllen = ll.length;
for (var i = 0; i < lllen; ++i) {
raStart[i] = pos;
pos += ll[i];
}
}
}
}
function setupViz() {
armgpu.setVizNodeValues = setVizNodeValues;
armgpu.setCameraOrientation = setCameraOrientation;
}
function Uint16Request (urlStr) {
this.urlStr = urlStr;
this.success = false;
this.u16Array = null;
var obj = this;
var req = new XMLHttpRequest();
req.onload = function(e) {
var arrayBuffer = req.response;
var data = new DataView(arrayBuffer);
var bpe = Uint16Array.BYTES_PER_ELEMENT;
obj.u16Array = new Uint16Array(data.byteLength / bpe);
var len = obj.u16Array.length;
for (var i = 0; i < len; ++i) {
obj.u16Array[i] = data.getUint16(i * bpe, true);
}
obj.success = true;
guardedRequestAnimFrame(render);
downloadMsg(-1);
// Option to print success msg
//addInner('msg2', 'Read ' + obj.urlStr + ' ' + obj.u16Array.length + ' bytes<br>');
};
req.open("GET", urlStr);
req.responseType = "arraybuffer";
req.send();
downloadMsg(1);
}
// End File Imports
// Provide the armgpu namespace
armgpu = {};
armgpu.Application = function() {
setupNodes();
setupTransistors();
setupParamsFromURL();
}
armgpu.Application.prototype.onLoad = function() {}
armgpu.Application.prototype.setNodes = function() {
armgpu.setVizNodeValues(nodes);
}
armgpu.Application.prototype.assert = function(cond, message) {
if (!cond) {
message = "Assertion failed: " + message;
alert(message);
throw new Error(message);
}
}
function onLoadArm() {
armgpu.appInstance = new armgpu.Application();
armgpu.appInstance.onLoad();
}
function setupParamsFromURL(){
if(location.search=="")
return
var queryParts=location.search.slice(1).split('&');
var userAddress = 0;
for(var i = 0; i < queryParts.length; ++i) {
var params = queryParts[i].split("=");
if (params.length != 2) {
break;
}
var name = params[0];
// chrome sometimes adds trailing slash
var value = params[1].replace(/\/$/,"");
// be (relatively) forgiving in what we accept
// developer quick and dirty startup
// load a test program: Address, Data and Reset
if (name == "a" && parseInt(value,16) != NaN) {
userAddress = parseInt(value,16);
}
else if (name == "d" &&
value.match(/[0-9a-fA-F]*/)[0].length == value.length) {
// data is in 32-bit words, as hex values, so groups of 8 digits
for (var j = 0; j < value.length; j+=8) {
userCode[userAddress] = parseInt(value.slice(j, j+8), 16);
userAddress += 4; // a byte address
}
}
}
}
function handleMessage(event){
var message = event.data.split(':');
if (message[0] == 'HILITE') {
var node = parseInt(message[1], 10);
var x = parseInt(message[2], 10);
var y = parseInt(message[3], 10);
if (node == 0) {
setStatus('location x:' + Math.round(x) + ' y:'+ Math.round(y));
}
else {
setStatus('node:' + node +
' (' + fixNodeName(nodenames[node]) + ') ' +
'state: ' + readNodeValueAsString(node),
'location x:' + Math.round(x) +
' y:'+ Math.round(y));
}
}
}
function fixNodeName(name){
if (name.substr(0,4) == 'core') {
var list = name.split('_');
var str = list[list.length-1];
if (str=='1' || str == '0') {
str = list[list.length-2] + '_' + str;
}
return(str);
}
return name;
}
</script>
</head>
<body id="bodyId" onload="onLoadArm()" onunload="teardown()">
<div id="mainlefthalf">
<div id="armgpu_view"
style="
background: gray;
position: absolute;
border: 2px solid gray;
width: 800px;
height:800px;
overflow: hidden;">
<canvas id="gl-canvas" width="1600" height="1600" style="width: 800px; height: 800px;">
Sorry, your browser doesn't support the HTML5 canvas element
</canvas>
</div>
</div>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment