Base64 encoded String URL friendly - javascript

I'm using this function for base64 decode/encode URL in javascript but i've seen many gives notice about making Base64 encoded String URL friendly and to use
// if this is your Base64 encoded string
var str = 'VGhpcyBpcyBhbiBhd2Vzb21lIHNjcmlwdA==';
// make URL friendly:
str = str.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, '');
// reverse to original encoding
str = (str + '===').slice(0, str.length + (str.length % 4));
str = str.replace(/-/g, '+').replace(/_/g, '/');
jsfiddle
I see it only replce + with - and \ with _ so what is the point! i mean why should i?

If you would not replace the characters they could get misinterpreted, like pointed out in this answer. This would result in either displaying wrong content or more likely displaying nothing.
For explanation:
In URLs the follwing characters are reserved: : / ? # [ ] # : $ & ' ( ) * + , ; =
Like pointed out in this answer you need 65 characters to encode data, but the sum of uppercase-, lowercase characters and digits is only 62. So it needs three additional characters which are + = /. These three are reserved. So you need to replace them. As of right now I am not entirely sure about -.

Related

what is the difference between encodeURI and decodeUri

I want to url encode a string in javascript:
but these 2 function calls give the same result:
encodeURI('g0sceq3EkiAQTvyaZ07C+C4SZQz9FaGTV4Zwq4HkAnc=') === decodeURI('g0sceq3EkiAQTvyaZ07C+C4SZQz9FaGTV4Zwq4HkAnc='); // true
both return g0sceq3EkiAQTvyaZ07C+C4SZQz9FaGTV4Zwq4HkAnc=.
Should the + sign and = sign not be encoded?
I thought = would be %3D and + would be %2B?
Use encodeURIComponent and decodeURIComponent. Note, neither function is idempotent; If you accidentally double-encode a component, you will have to double-decode it -
console.log
( encodeURIComponent ("=") // %3D
, decodeURIComponent ("%3D") // =
, encodeURIComponent ("%3D") // %253D
, decodeURIComponent ("%253D") // %3D
, encodeURIComponent (encodeURIComponent ("=")) // %253D
, decodeURIComponent (decodeURIComponent ("%253D")) // =
)
The other answer does not answer your question.
The answer is: you think + should be encoded but it is a safe URI character. See Safe characters for friendly url
const a = encodeURI("a%")
const b = decodeURI("a")
console.log(a)
console.log(b)
console.log(a === b) /// false

Javascript , encodeURI failed to encode round bracket "("

I have cookie value which contains round bracket " e.g: demo (1)"
When I try to encode with encodeURI , the round bracket ( is not encoded to %28 , what is the alternative to encode the special characters like round brackets
encodeURI() encodes special characters, except: , / ? : # & = + $ #.
One can use encodeURIComponent() to encode the above character.
You can write custom method to encode ( to %28.
Example :
var uri = "my test.asp?(name";
var res = encodeURI(uri);
res.replace("(", "%28");
As pointed out in the comment below, string#replace will remove the first occurrence, one can use string#replaceAll i.e. res.replaceAll("(", "%28") or string#replace with global flag i.e. res.replace(/\(/g, "%28") to remove all occurrences.
const uri = "my test.asp?(n(a(m(e",
res = encodeURI(uri);
console.log(res.replaceAll("(", "%28"));
NOTE :
encodeURI() will not encode: ~!##$&*()=:/,;?+'
encodeURIComponent() will not encode: ~!*()'
To encode uri components to be RFC 3986 -compliant - which encodes the characters !'()* - you can use:
function fixedEncodeURIComponent(str) {
return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
return '%' + c.charCodeAt(0).toString(16);
});
}
Taken from just before Examples-section at: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
For reference, see: https://www.rfc-editor.org/rfc/rfc3986
encodeURI only encodes reserved characters so this function should not be expected to encode parentheses.
You could write your own function to encode all the characters in the string, or just create a custom list of characters you want to encode.
Fiddle
function superEncodeURI(url) {
var encodedStr = '', encodeChars = ["(", ")"];
url = encodeURI(url);
for(var i = 0, len = url.length; i < len; i++) {
if (encodeChars.indexOf(url[i]) >= 0) {
var hex = parseInt(url.charCodeAt(i)).toString(16);
encodedStr += '%' + hex;
}
else {
encodedStr += url[i];
}
}
return encodedStr;
}
Based on encodeURIComponent docs by Mozilla
encodeURIComponent escapes all characters except:
A-Z a-z 0-9 - _ . ! ~ * ' ( )
So, the only characters we don't want to scape are: A-Z a-z 0-9.
So this function does it:
function encodeUriAll(value) {
return value.replace(/[^A-Za-z0-9]/g, c =>
`%${c.charCodeAt(0).toString(16).toUpperCase()}`
);
}

Regex match cookie value and remove hyphens

I'm trying to extract out a group of words from a larger string/cookie that are separated by hyphens. I would like to replace the hyphens with a space and set to a variable. Javascript or jQuery.
As an example, the larger string has a name and value like this within it:
facility=34222%7CConner-Department-Store;
(notice the leading "C")
So first, I need to match()/find facility=34222%7CConner-Department-Store; with regex. Then break it down to "Conner Department Store"
var cookie = document.cookie;
var facilityValue = cookie.match( REGEX ); ??
var test = "store=874635%7Csomethingelse;facility=34222%7CConner-Department-Store;store=874635%7Csomethingelse;";
var test2 = test.replace(/^(.*)facility=([^;]+)(.*)$/, function(matchedString, match1, match2, match3){
return decodeURIComponent(match2);
});
console.log( test2 );
console.log( test2.split('|')[1].replace(/[-]/g, ' ') );
If I understood it correctly, you want to make a phrase by getting all the words between hyphens and disallowing two successive Uppercase letters in a word, so I'd prefer using Regex in that case.
This is a Regex solution, that works dynamically with any cookies in the same format and extract the wanted sentence from it:
var matches = str.match(/([A-Z][a-z]+)-?/g);
console.log(matches.map(function(m) {
return m.replace('-', '');
}).join(" "));
Demo:
var str = "facility=34222%7CConner-Department-Store;";
var matches = str.match(/([A-Z][a-z]+)-?/g);
console.log(matches.map(function(m) {
return m.replace('-', '');
}).join(" "));
Explanation:
Use this Regex (/([A-Z][a-z]+)-?/g to match the words between -.
Replace any - occurence in the matched words.
Then just join these matches array with white space.
Ok,
first, you should decode this string as follows:
var str = "facility=34222%7CConner-Department-Store;"
var decoded = decodeURIComponent(str);
// decoded = "facility=34222|Conner-Department-Store;"
Then you have multiple possibilities to split up this string.
The easiest way is to use substring()
var solution1 = decoded.substring(decoded.indexOf('|') + 1, decoded.length)
// solution1 = "Conner-Department-Store;"
solution1 = solution1.replace('-', ' ');
// solution1 = "Conner Department Store;"
As you can see, substring(arg1, arg2) returns the string, starting at index arg1 and ending at index arg2. See Full Documentation here
If you want to cut the last ; just set decoded.length - 1 as arg2 in the snippet above.
decoded.substring(decoded.indexOf('|') + 1, decoded.length - 1)
//returns "Conner-Department-Store"
or all above in just one line:
decoded.substring(decoded.indexOf('|') + 1, decoded.length - 1).replace('-', ' ')
If you want still to use a regular Expression to retrieve (perhaps more) data out of the string, you could use something similar to this snippet:
var solution2 = "";
var regEx= /([A-Za-z]*)=([0-9]*)\|(\S[^:\/?#\[\]\#\;\,']*)/;
if (regEx.test(decoded)) {
solution2 = decoded.match(regEx);
/* returns
[0:"facility=34222|Conner-Department-Store",
1:"facility",
2:"34222",
3:"Conner-Department-Store",
index:0,
input:"facility=34222|Conner-Department-Store;"
length:4] */
solution2 = solution2[3].replace('-', ' ');
// "Conner Department Store"
}
I have applied some rules for the regex to work, feel free to modify them according your needs.
facility can be any Word built with alphabetical characters lower and uppercase (no other chars) at any length
= needs to be the char =
34222 can be any number but no other characters
| needs to be the char |
Conner-Department-Store can be any characters except one of the following (reserved delimiters): :/?#[]#;,'
Hope this helps :)
edit: to find only the part
facility=34222%7CConner-Department-Store; just modify the regex to
match facility= instead of ([A-z]*)=:
/(facility)=([0-9]*)\|(\S[^:\/?#\[\]\#\;\,']*)/
You can use cookies.js, a mini framework from MDN (Mozilla Developer Network).
Simply include the cookies.js file in your application, and write:
docCookies.getItem("Connor Department Store");

javascript's String.length returns wrong character count

I came accross a strange javascript behavior today which is probably due to some character encoding issue. The length function returns two different character count for what is apparently the exact same string.
In one instance the string was copy pasted from a database value, in the second instance I manually wrote the characters with my keyboard.
I'm sure this is UTF related but I cant figure how to get the "correct" character count.
Is there a way to know which encoding the faulty string is in and "fix" it somehow?
Is there a way to force every strings in my app to be UTF-8 ?
Is there a hidden character somewhere ?
Thanks for your help
var utils = {
/**
* cleans up our url before db insertion
*
* #param url
* #returns {String} the cleaned url
*/
cleanUrl : function(url){
url = url.trim().toLowerCase();
if(url.includes('?'))return url;
var lastChar = url.charAt(url.length-1);
console.log('lastchar = ' + lastChar);
if(lastChar == '/'){
url=url.substring(0, url.length-1);
}
return url;
},
doTest : function(){
var url = "https://bitcointalk.org/‎"; //this string was taken from DB
console.log('url length ' + url.length);
console.log('url length ' + url.trim().length);
var cleaned = this.cleanUrl(url);
console.log('cleaned length ' + cleaned.length);
console.log('cleaned ' + cleaned);
console.log('------------------------------');
var url2 = "https://bitcointalk.org/"; //this string was manually written
console.log('url2 length ' + url2.length);
console.log('url2 length ' + url2.trim().length);
var cleaned2 = this.cleanUrl(url2);
console.log('cleaned2 length ' + cleaned2.length);
console.log('cleaned2 ' + cleaned2);
}
};
utils.doTest()
And here is the output :
url length 25
url length 25
lastchar = ‎
cleaned length 25
cleaned https://bitcointalk.org/‎
------------------------------
url2 length 24
url2 length 24
lastchar = /
cleaned2 length 23
cleaned2 https://bitcointalk.org
You are correct! There is a secret character encoded from the DB you can see if you copy both of your strings out and try it in your browser console.
I have tested your string which is copied from DB and it contains some special characters. So for that you can use encodeURIComponent() method of javascript on that string and then save that encoded string in DB and while retrieving perform decodeURIComponent() on that string.

Javascript regular expression adjustment

Using mootools I have a regex like this:
new RegExp('^([^\\D'+ separator +']+)(\\d{2})');
In a string it inserts the char defined in separator after every 2 characters. I want it to insert only for the last two.
Example:
String Result
123456 12.34.56 // what it does now
123456 1234.56 // what it should do
I don't have much experience with regex so any help or link to a decent tutorial is appreciated.
If your string only consists of digits, isn't this the same as divide by 100?
'' + str / 100
It might depend on locale though ;-)
I can improve this answer if you have more edge cases I can work with.
If you absolutely must just regular expressions, you could always use this:
'123456'.replace(/(.)(\d{2})$/, function($0, $1, $2) {
return $1 + '.' + $2;
});
This would protect you against strings that would otherwise result in NaN, such as 'foo'.
Don't use regex for this:
var str = "123456".split('').reverse().join('');
var x = str.substring(0,2) + '.' + str.substring(2);
var final = x.split('').reverse().join('');
console.log(final);
Live DEMO
Of course you can check if the string length is bigger than 2
if (str.length > 2)
// ...
Or use string slice function:
str ="123456";
str.slice(0, -2) + "." + str.slice(-2);
How does it work?
I'll break it into pieces:
// Start at the beginning of the string grab all the chars
// and stop two chars before the end of the string
str.slice(0, -2)
// Start at two chars before the end of the string, take all the chars until
// the end of the string.
str.slice(-2);
Assume the string always has more than 2 characters:
str.slice(0, -2) + "." + str.slice(-2)
Reference to String.slice.

Categories

Resources