How to make a simple encoder and decoder? - javascript

I have the following code:
<DOCTYPE HTML>
<html>
<body>
<script type="text/javascript">
//Chat Encoder
//Made by Hducke aka Hunter Ducker
//VARS
var userInputA = "";
var userInputB = "";
var result = userInputB.split("");
//FUNCTIONS
var encodeMessage = function(){
var output = "";
userInputB = prompt("Type your message here:", "PLEASE TYPE YOUR MESSAGE IN LOWER CASE!");
for(var i = 0; i <= result.length; i++){
switch(result[i]){
case("a"):
result[i] = "1";
break;
case("b"):
result[i] = "2";
break;
case("c"):
result[i] = "3";
break;
}
var tempStr = "";
result[i] + tempStr;
}
return tempStr;
}
var decodeMessage = function(){
}
var promptUser = function(){
var tempBool = true;
while(tempBool){
userInputA = prompt("Type '1' to encode a message and '2' to decode a message!", "Type '1' or '2' here.");
switch(userInputA){
case("1"):
encodeMessage();
tempBool = false;
break;
case("2"):
decodeMessage();
tempBool = false;
break;
default:
alert("Try again. Please type a '1' or a '2'.");
}
}
}
var printMessage = function(){
alert(encodeMessage);
}
//LOGIC
promptUser();
printMessage();
</script>
</body>
</html>
Info: The way it is atm is it takes in the users input userInputB and parses it into separate characters. Then it sets the characters to a different character (scambles the character). Then it outputs the string to the user. My goal is to have it to where you can enter a message I love this website! and turn it into 1 2324 5654 7503947. Then another user can enter the encoded message and the decodeMessage function will decode the message and output it to the user.
First issue: It won't currently work as is.*
*EDIT: Now when I run the code after fixing the result[i].
Output I Get Now
Second issue: How can I do this (IE. Is there a better way of doing this)
Any tips can help. I'm kinda a noob at javascript. Thanks!

The first problem is with your input; result is not going to be updated when the user enters the prompt.
function encodeMessage() {
var output = '';
userInputB = prompt(...);
result = userInputB.split('');
...
}
The second problem is the encoding itself. Instead of using a giant switch, create an algorithm to perform the encoding. In your case, you have a simple 1:1 mapping of a character to a number, conveniently in the natural order.
Did you know that your computer stores those letters as numbers? 'a' is 97, 'b' is 98, etc. so you could simply subtract 96 from the character to get a=1, b=2, etc.
However, this poses a problem for your decoder once you reach 'j'. "java" is going to be turned into "101221", and if you simply perform the reverse of your encoder on that, you'll end up with "a`abba".
One option would be to return to your encoding scheme and the ASCII table. '1' is character 49; perhaps you could subtract 48 from your characters instead? 'a' would then become '1' (not much different from 1) and so on. 'j' becomes ':', and if you encode "java" you get ":1F1".
Once you're doing that, the reverse of your encoding scheme will become your decoder. Iterate over the encoded string, and add 48 instead of subtracting it.

UPDATE
I've updated the http://jsfiddle.net/ntyt4/5/ with a sample scenario of the encoding and decoding process. It should give you enough to get started.
A simpler way would be to use a dictionary with keys and their translated values. You could store this in an object literal as:
var translation = {
"a": 1,
"b": 2,
"c": 3,
"d": "A"
};
I've included a jsfiddle to show you an example. Just change the textbox value to one value to see the translation.
One thing to keep in mind though is that you will have to add every single character that needs to be translated to the object literal. For example "a" will not translate the upper case version "A" for you because it is a different character.

I don't know very well the javascript but you have three options:
Mapping the chars with two Vector
If you want to include the simple characters you need 25(a-z)+25(A-Z)+9(0-9)=59 conversion.
You can do this with an algoritm that if found a letter in the first vector for example at index "6", take the value from the corrispondent position in the second vector.
Decoding is the same way, only take from second vector and convert it in the equivalent for the first vector.
ASCII Table
The char letter '0' casted in integer is 48.
From 48-57 you have the number, in the range 65-90 you have the Upper char and in the range 97-122 you have the lower char. If you try to subtrack for example two your text is encoded in a simple system.
MD5 Algoritm
You can use/create a function that generate the md5 hash of a text, for example "encoding" in md5 is "84bea1f0fd2ce16f7e562a9f06ef03d3". If you want use an encript system for encript an area this is the better way.

Related

Why method setValue doesn't output same as Browser.msgBox?

Since I could not make .toFixed(2) to work I designed my own piece of code to add desired decimal digits after the "." by simple joining two strings with + sign.
While Browser.msgBox outputs the 2 strings joined correctly as "1.00",
it seems like getRange.setValue outputs only the first of the 2 strings as "1" :(
function myFunction() {
var ss_calc = SpreadsheetApp.openById("1cFt0DbnpWGHquKk4ijxdKhwkaF8GhumWDWjTpHuSXbQ");
var sheet_calc = ss_calc.getSheetByName("Calcs");
var ss_source = SpreadsheetApp.openById("1gXeXmiw9EnzQXaiE7H8_zrilE2zyotlSuuIS8X9IxfQ");
var sheet_source = ss_source.getSheetByName("Farmah");
var decDig = ""; var strDec = ""; var impVal = "";
impVal = sheet_source.getRange(12,7).getValue().toString();
if (JSON.stringify(impVal).indexOf(".")>-1)
{ if (JSON.stringify(impVal).split(".")[1].length < 2 )
{
if (JSON.stringify(impVal).split(".")[1].length < 1)
{
decDig = "00";
}
else
{
decDig = "0";
}
}
}
else
{
decDig = ".00";
}
var strDec = impVal.toString() + decDig.toString();
Browser.msgBox(JSON.stringify(impVal).indexOf(".")+ "\\n" +
impVal.toString()+ "\\n" +
decDig+ "\\n" +
strDec);
sheet_calc.getRange(1,1).setValue(strDec);
}
From sheet_calc.getRange(1,1).setValue(strDec); I am expecting to get output "1.00" but I get only "1" :(
What am I missing?
Here are the links to google spreadsheets ( anyone with the link can edit :)
(above code has to be triggered manually by script editor in the first spreadsheet here under):
https://docs.google.com/spreadsheets/d/1cFt0DbnpWGHquKk4ijxdKhwkaF8GhumWDWjTpHuSXbQ/edit?usp=sharing
https://docs.google.com/spreadsheets/d/1gXeXmiw9EnzQXaiE7H8_zrilE2zyotlSuuIS8X9IxfQ/edit?usp=sharing
You want to put the value of 1.00 to a cell "A1".
If my understanding is correct, how about this modification? I think that the reason of your issue is that the value by putting by setValue() is converted to the number. By this, 1 is shown. In order to put the value as 1.00, I think that there are 3 patterns. Please select one of them for your situation.
Pattern 1:
In this pattern, from your question, the value is put as a string using setNumberFormat("#").
From:
sheet_calc.getRange(1,1).setValue(strDec);
To:
sheet_calc.getRange(1,1).setNumberFormat("#").setValue(strDec);
Pattern 2:
In this pattern, from your question, the format of cell is set using setNumberFormat("0.00").
From:
sheet_calc.getRange(1,1).setValue(strDec);
To:
sheet_calc.getRange(1,1).setNumberFormat("0.00").setValue(strDec);
Pattern 3:
In this pattern, from the script of your shared Spreadsheet, When decDig is ".00", the format is set.
From:
sheet_calc.getRange(x+6,c).setValue(strDec);
To:
var range = sheet_calc.getRange(x+6,c);
if (decDig) {
range.setNumberFormat("0.00").setValue(strDec); // or setNumberFormat("#")
} else {
range.setValue(strDec);
}
Reference:
setNumberFormat(numberFormat)
If I misunderstood your question and this was not the result you want, I apologize.
From sheet_calc.getRange(1,1).setValue(strDec); I am expecting to get output "1.00" but I get only "1" :(
Google Sheets, as well as other spreadsheet apps, have an automatic data type assignation, so things that look as numbers are converted to Google Sheets number data type, etc.
You could prepend an ' to force that a value be treated as text or you could set the number format in such way that numbers are displayed with two decimals. The cell formatting could be applied in advance, i.e., by using the Google Sheets UI commands or you could use Apps Script to set the format for you.

Javascript Math.log() help wanted

World!
I'm trying to create a program in Javascript that takes the log of a number typed into an HTML input. Unfortunately i've encountered a problem where it wont accept the string with the .replace().
Its Function:
I.E: When log(10) is calculated, the function should first remove the first 4 char's "log(" next remove the last parenthesis ")" and then take the log of the no. between.
HTML includes style elements, button and input form and an output < DIV >.
//Function
function calculate()
{
var inputString = document.getElementById("inpstr");
var output = document.getElementById("output");
//TESTING CODE
/*
if (inputString.value.startsWith("log(").endsWith(")"))
{
console.log(output.innerHTML = inputString.value.substring(4, 20).replace(")", ""));
}
else
{
output.innerHTML = "false";
}
*/
//Math.log() calc *****DOESNT WORK*****
if (inputString.value.startsWith("log(").endsWith(")"))
{
output.innerHTML = Math.log(inputString.value.replace(")", "").substring(4, 20));
}
else
{
output.innerHTML = inputString.value;
}
event.preventDefault();
}
If someone can give me an effective solution that would be much appreciated.
Thanks,
Syntax
Since Math.log() accepts only number values and you're trying to pass a string to it, you should first parse this value into a float number and then pass it to the log function:
let val = parseFloat(inputString.value.replace(")", "").substring(4, 20));
output.innerHTML = Math.log(val);
I'm guessing I got downvoted for being lazy, so here is the quick info. Gonras got it right relating to what you want to extract, but he forgot to check that what's being input is actually a log.
That's where the regex below comes in handy! I'm matching the field to:
^ start of word, since we want to match the entire field.
log(
([-.\d])) any consecutive sequence () of numbers (\d), -, and '.', represented by the []. The \(...\) makes sure to save this inner part for later.
$ is end of word, see 1.
res will be null if there is no match. Otherwise, res[0] is the entire match (so the entire input field) and res[1] is the first 'capture group', at point 3 - which is presumably the number.
This of course fails for multiple "-" inside, or "." etc... so think it over.
//Function
function calculate()
{
var inputString = document.getElementById("inpstr");
var output = document.getElementById("output");
var res = /^log\(([-.\d]*)\)$/.exec(inputString.value);
if (res)
output.innerHTML = Math.log(res[1]);
else
output.innerHTML = res;
}
document.getElementById("output").innerHTML='start';
calculate()
<div id='output'></div>
<input id='inpstr' value='log(2.71828)'></input>
If I wanted to fix your if to supplement Gonras's solution:
if (inputString.value.startsWith("log(") && inputString.value.endsWith(")"))
Yours fails since startsWith() returns a boolean, which obviously doesn't have a endsWith function.

Is it possible to use code to transform a list in format 'list': "translation"?

I would like to be able to change a list of words in my coding, e.g.
var words= {
AFK Away from the keyboard 4U For you B4N By for now BBL Be back later BDAY Birthday CBA Can't be asked }
changed to this format:
var words= {
'AFK': "Away from the keyboard", '4U': "For you", 'B4N': "By for now", 'BBL': "Be back later", 'BDAY': "Birthday", 'CBA': "Can't be asked",
}
without having to change each word into the format manually using HTML/JavaScript. However I understand that this might not be possible, but I thought I'd see if anyone had an I idea on how to do it anyway. From what I read it looks as if I'll have to use Python and a Database, but I don't know anything about python what so ever really so I was hoping (probably vainly) that there is some HTML/JavaScript code that I haven't seen that solves this!
I found a similar question here, but it wasn't really what I wanted as it uses python: [turning data into a list
The thing I want to do is change all words in this format: e.g
AFK Away from the Keyboard
to a format with
'AFK': "Away from the keyboard",
the aim of this code is to translate text abbreviations to real English words which it is already doing, but in order to get a decent amount of words to translate I need to get words in the above format which would take forever if I formated each one individually. here is the rest of the code if that helps:
function replacer() {
var text= document.getElementById("textbox1").value;
for (var modifiers in translationwords){
text = text.replace(new RegExp('\\b' + modifiers + '\\b', 'gi'), translationwords[modifiers]); }
document.getElementById("textbox2").value=text;
document.getElementById("add").onclick= function storage() {
if(!document.cookie) document.cookie = "";
document.cookie = document.cookie +"<li>"+document.getElementById("textbox1").value+ ":"+"</li>";
document.cookie = document.cookie +"<li>" + document.getElementById("textbox2").value+ "</li>";
document.getElementById("array").innerHTML= document.cookie;
}
}
function textdelete(x) {
if (x.value=="ENTER TRANSLATION HERE"){
x.value="";
};
}
Thank You
If your words were in a string to begin with, then it would be arguably possible to translate it into an object the way you want it, but it might not be the most accurate translation.
Since it looks like all the abbreviations are all upper case and without spaces, we can look through the string, and set the all caps/numbers 'words' as properties, with the following string of text as the value. In javascript, something like this would work.
//set words as string
var string = "AFK Away from the keyboard 4U For you B4N By for now BBL Be back later BDAY Birthday CBA Can't be asked";
// create empty dictionary for storage
var dictionary = {};
// use regex to find all abbreviations and store them in an array
var abbreviations = string.match(/[A-Z0-9]+(?![a-z])\w/g);
// returns ["AFK", "4U", "B4N", "BBL", "BDAY", "CBA"]
// use regex to replace all abbreviations with commas...
englishWords = string.replace(/[A-Z0-9]+(?![a-z])\w/g, ',');
// Edit (see below):
englishWords = englishWords.replace(/\W,\W/g,',');
// End edit
// then split string into array based on commas
englishWords = englishWords.split(',').slice(1);
// finally loop over all abbreviations and add them to the dictionary with their meaning.
for(var i = 0; i < abbreviations.length; i++){
dictionary[abbreviations[i]] = englishWords[i];
}
Edit: the above solution still might have white space at the beginning or end of each english string. You can add this line of code just before splitting the string to remove the white space.
englishWords = englishWords.replace(/\W,\W/g,',');
Assuming you have the data as a list in python, or as a string, or that you can get it into that format:
>>> lst = 'AFK Away from the keyboard 4U For you B4N By for now BBL Be back later BDAY Birthday CBA Can\'t be asked'.split()
>>> lst
['AFK', 'Away', 'from', 'the', 'keyboard', '4U', 'For', 'you', 'B4N', 'By', 'for', 'now', 'BBL', 'Be', 'back', 'later', 'BDAY', 'Birthday', 'CBA', "Can't", 'be', 'asked']
Further assuming that the keywords are always in all-uppercase and that the values are never in all uppercase, and that there are no duplicate keys, you can create the following dictionary:
>>> keys = [x for x in lst if x.upper() == x]
>>> {keys[i]:' '.join(lst[lst.index(keys[i]):lst.index(keys[i+1])]) for i in range(len(keys)-1)}
{'BDAY': 'BDAY Birthday', 'BBL': 'BBL Be back later', '4U': '4U For you', 'B4N': 'B4N By for now', 'AFK': 'AFK Away from the keyboard'}
Let's say that this is your list of words:
["AFK","Away","from","the","keyboard","4U","For","you","B4N","By","for","now","BBL","Be","back","later","BDAY","Birthday","CBA","Can't","be","asked"]
Now, we can change that into an object simply by using regular JavaScript without any database or back-end langauge like Python.
var list = ["AFK","Away","from","the","keyboard","4U","For","you","B4N","By","for","now","BBL","Be","back","later","BDAY","Birthday","CBA","Can't","be","asked"] /*What we have*/;
var code = {} /*What we want*/;
var currKey = null /*Our current key*/, hasBeenSet = false /*Whether or not the property at our current key has been set*/;
for (var i = 0; i < words.length; i++) {
//If the current word is an abbreviation...
if (words[i] === words[i].toUpperCase()) {
currKey = words[i]; //We set currKey to it
hasBeenSet = false; //We make hasBeenSet false
}
//Otherwise, if the property at current key has been set, we add on to it.
else if (hasBeenSet) code[currKey] += " "+words[i];
//Otherwise, the property at current key hasn't been set...
else {
code[currKey] = words[i]; //We set the property to the current word
hasBeenSet = true; //We make hasBeenSet true
}
}
code //{ AFK: "Away from the keyboard", 4U: "For you", B4N: "By for now", BBL: "Be back later", BDAY:"Birthday", CBA:"Can't be asked" }

Regex split string and check if string is of type

Aanval op Vlemis (499|453) C44
This is what the string looks like. Though it's actually like this: "Aanval op variable (variable) variable
What I want to do is 1: get the coordinates (I already have this), 2 get Vlemis (first variable), get C44 (third variable) and check to see if the string is of this type.
My code:
$("#commands_table tr.nowrap").each(function(){
var text = $(this).find("input[id*='editInput']").val();
var attackername= text.match(/(?=op)[\s|\w]*(?=\()/);
var coordinates = text.match(/\(\d{1,3}\|\d{1,3}\)/);
});
Coordinates works, attackername however doesn't.
Html:
<span id="labelText[6]">Aanval op Vlemis (499|453) C44</span>
You should use one regex to take everything :
var parts = text.match(/(\w+)\s*\((\d+)\|(\d+)\)\s*(\w+)/).slice(1);
This builds
["Vlemis", "499", "453", "C44"]
If you're not sure the string is valid, test like this :
var parts = text.match(/(\w+)\s*\((\d+)\|(\d+)\)\s*(\w+)/);
if (parts) {
parts = parts.slice(1);
// do things with parts
} else {
// no match, yell at the user
}

ExtJS 4.1.1: Evaluating a field in a grid

I'm struggling with a ExtJS 4.1.1 grid that has editable cells (CellEditing plugin).
A person should be able to type a mathematic formula into the cell and it should generate the result into the field's value. For example: If a user types (320*10)/4 the return should be 800. Or similar if the user types (320m*10cm)/4 the function should strip the non-mathematical characters from the formula and then calculate it.
I was looking to replace (or match) with a RegExp, but I cannot seem to get it to work. It keeps returning NaN and when I do console.log(e.value); it returns only the originalValue and not the value that I need.
I don't have much code to attach:
onGridValidateEdit : function(editor,e,opts) {
var str = e.value.toString();
console.log(str);
var strCalc = str.match(/0-9+-*\/()/g);
console.log(strCalc);
var numCalc = Number(eval(strCalc));
console.log(numCalc);
return numCalc;
},
Which returns: str=321 strCalc=null numCalc=0 when I type 321*2.
Any help appreciated,
GR.
Update:
Based on input by Paul Schroeder, I created this:
onGridValidateEdit : function(editor,e,opts) {
var str = e.record.get(e.field).toString();
var strCalc = str.replace(/[^0-9+*-/()]/g, "");
var numCalc = Number(eval(strCalc));
console.log(typeof numCalc);
console.log(numCalc);
return numCalc;
},
Which calculates the number, but I am unable to print it back to the grid itself. It shows up as "NaN" even though in console it shows typeof=number and value=800.
Final code:
Here's the final code that worked:
onGridValidateEdit : function(editor,e,opts) {
var fldName = e.field;
var str = e.record.get(fldName).toString();
var strCalc = str.replace(/[^0-9+*-/()]/g, "");
var numCalc = Number(eval(strCalc));
e.record.set(fldName,numCalc);
},
Lets break this code down.
onGridValidateEdit : function(editor,e,opts) {
var str = e.value.toString();
What listener is this code being used in? This is very important for us to know, here's how I set up my listeners in the plugin:
listeners: {
edit: function(editor, e){
var record = e.record;
var str = record.get("your data_index of the value");
}
}
Setting it up this way works for me, So lets move on to:
var strCalc = str.match(/0-9+-*\/()/g);
console.log(strCalc);
at which point strCalc=null, this is also correct. str.match returns null because your regex does not match anything in the string. What I think you want to do instead is this:
var strCalc = str.replace(/[^0-9+*-]/g, "");
console.log(strCalc);
This changes it to replace all characters in the string that aren't your equation operators and numbers. After that I think it should work for whole numbers. I think that you may actually want decimal numbers too, but I can't think of the regex for that off the top of my head (the . needs to be escaped somehow), but it should be simple enough to find in a google search.

Categories