I have an actionscript class that serializes and unserializes data compatible with php's serialization functions. I expanded it to support binary data but now the unserialization does not seem to work.
For example, this data is not unserialized correctly:
a:2:{i:0;s:1:"õ";i:1;a:2:{i:0;s:32:"mÎiyl·T=doÁ°ýNd_¤ÁÝ`:AåÁˆ#";i:1;s:32:"ÿ^ò`d^|“T¶&JÐÞG[±iÏ*Ÿ!–Ü’IÍ";}}
Here is the class:
package pack
{
import flash.utils.ByteArray;
import flash.utils.Dictionary;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.core.*;
use namespace mx_internal;
public class Serializer extends Object
{
public static const version:String = "3.0.0";
mx_internal static var c:uint;
mx_internal static var pattern:RegExp = /[A-Z][a-z]{2}, \d{2} [A-Z][a-z]{2} \d{4} \d{2}:\d{2}:\d{2} \+|\-\d{4}/g
public static function serialize(data:*):ByteArray
{
var bas:ByteArray = new ByteArray();
var tmp:ByteArray = new ByteArray();
var i:int = 0;
var key:String;
if(data is Boolean){
bas.writeUTFBytes('b:');
bas.writeUnsignedInt(data);
bas.writeUTFBytes(';');
} else if(data is int){
bas.writeUTFBytes('i:');
bas.writeUTFBytes(data);
bas.writeUTFBytes(';');
} else if(data is Number){
bas.writeUTFBytes('d:');
bas.writeUTFBytes(data);
bas.writeUTFBytes(';');
} else if(data is ByteArray){
bas.writeUTFBytes('s:');
bas.writeUTFBytes(data.length.toString());
bas.writeUTFBytes(':"');
bas.writeBytes(data);
bas.writeUTFBytes('";');
} else if(data is String){
bas.writeUTFBytes('s:');
bas.writeUTFBytes(data.length.toString());
bas.writeUTFBytes(':"');
bas.writeUTFBytes(data);
bas.writeUTFBytes('";');
} else if(data is Date){
bas.writeUTFBytes('s:');
bas.writeUTFBytes(data.toString().length.toString());
bas.writeUTFBytes(':"');
bas.writeUTFBytes(data);
bas.writeUTFBytes('";');
} else if(data is ArrayCollection){
for(key in data){
tmp.writeBytes(Serializer.serialize(i));
tmp.writeBytes(Serializer.serialize(data[key]));
i += 1;
}
bas.writeUTFBytes('a:');
bas.writeUTFBytes(i.toString());
bas.writeUTFBytes(':{');
bas.writeBytes(tmp);
bas.writeUTFBytes('}');
} else if(data is Array){
for(key in data){
tmp.writeBytes(Serializer.serialize(i));
tmp.writeBytes(Serializer.serialize(data[key]));
i += 1;
}
bas.writeUTFBytes('a:');
bas.writeUTFBytes(i.toString());
bas.writeUTFBytes(':{');
bas.writeBytes(tmp);
bas.writeUTFBytes('}');
} else if(data is Object){
for(key in data){
tmp.writeBytes(Serializer.serialize(key));
tmp.writeBytes(Serializer.serialize(data[key]));
i += 1;
}
bas.writeUTFBytes('O:8:"stdClass":');
bas.writeUTFBytes(i.toString());
bas.writeUTFBytes(':{');
bas.writeBytes(tmp);
bas.writeUTFBytes('}');
} else if(data == null || data == undefined){
bas.writeUTFBytes('N;');
} else {
bas.writeUTFBytes('i:0;');
}
return bas;
}
public static function unserialize(data:ByteArray):*
{
Serializer.c = 0;
return Serializer.unserialize_internal(data);
}
mx_internal static function unserialize_internal(data:ByteArray):*
{
var result:*;
var tmpvar:*;
var tmp:Array = new Array();
var type:String = Serializer.charAt(data, Serializer.c);
var pos:uint = 0;
var islist:Boolean = true;
var i:uint;
switch(type){
case "N":
Serializer.c += 2;
break;
case "b":
result = Serializer.substr(data, Serializer.c+2, 1).toString() == '1'
//result = data.substr(Serializer.c+2, 1) == "1"
Serializer.c += 4
break;
case "i":
tmp.push(Serializer.indexOf(data, ';', Serializer.c));
//tmp.push(data.indexOf(";", Serializer.c))
pos = Serializer.c+2
Serializer.c = tmp[0]+1
result = int(Serializer.substring(data, pos, tmp[0]));
//result = int(data.substring(pos,tmp[0]))
break;
case "d":
tmp.push(Serializer.indexOf(data, ';', Serializer.c));
//tmp.push(data.indexOf(";", Serializer.c))
pos = Serializer.c + 2
Serializer.c = tmp[0]+1
result = Number(Serializer.substring(data, pos, tmp[0]));
//result = Number(data.substring(pos,tmp[0]))
break;
case "s":
tmp.push(int(Serializer.indexOf(data, ':', Serializer.c+2)));
//tmp.push(int(data.indexOf(":", Serializer.c+2)))
tmp.push(tmp[0]+2)
pos = Serializer.c+2
tmp.push(0)
tmp.push(int(Serializer.substring(data, pos, tmp[0])));
//tmp.push(int(data.substring(pos, tmp[0])));
if(tmp[3] == 0)
{
result = "";
Serializer.c = pos+5
} else {
var lenc:uint = Serializer.stringBCLenght(data, Serializer.c, tmp[3]);
if(lenc != tmp[3])
{
result = Serializer.substr(data, tmp[0]+2, lenc);
//result = data.substr(tmp[0]+2, lenc);
Serializer.c = tmp[0]+4+lenc;
} else {
result = Serializer.substr(data, tmp[0]+2, tmp[3]);
//result = data.substr(tmp[0]+2, tmp[3]);
Serializer.c = tmp[0]+4+tmp[3];
}
}
if(Serializer.pattern.test(result))
{
result = new Date(result)
}
break;
case "a":
//result:ByteArray;
pos = Serializer.c+2
tmp.push(int(Serializer.indexOf(data, ":", pos)))
tmp.push(int(Serializer.substring(data, pos, tmp[0])))
//tmp.push(int(data.indexOf(":", pos)))
//tmp.push(int(data.substring(pos, tmp[0])))
Serializer.c = tmp[0]+2
result = []
for(i = 0; i < tmp[1]; i++){
tmpvar = Serializer.unserialize_internal(data)
result[tmpvar] = Serializer.unserialize_internal(data)
if(!(tmpvar is int) || tmpvar < 0){
islist = false
}
}
if(islist){
tmp.push([])
for(var key:uint = 0; key < result.length; key++){
pos = tmp[2].length
while(key > pos){
tmp[2].push(null)
pos +=1
}
tmp[2].push(result[key])
}
result = tmp[2]
}
Serializer.c += 1
break;
case "O":
pos = Serializer.indexOf(data, "\"", Serializer.c)+1;
Serializer.c = Serializer.indexOf(data, "\"", pos);
tmp.push(Serializer.substring(data, pos, Serializer.c))
//pos = data.indexOf("\"", Serializer.c)+1;
//Serializer.c = data.indexOf("\"", pos);
//tmp.push(data.substring(pos, Serializer.c))
Serializer.c += 2
i = Serializer.c
Serializer.c = Serializer.indexOf(data, ":", i)
i = int(Serializer.substring(data, i, Serializer.c))
//Serializer.c = data.indexOf(":", i)
//i = int(data.substring(i, Serializer.c))
Serializer.c +=2;
result = {};
var tmps:*;
while(i > 0){
tmps = Serializer.unserialize_internal(data)
result[tmps] = Serializer.unserialize_internal(data)
i -= 1
}
break;
}
return result;
}
mx_internal static function stringCLenght(data:String, from:uint = 0, len:uint = 0):int
{
var i:uint;
var j:uint = len;
var startIndex:uint = from + 4 + len.toString().length;
for (i = 0; i < j; i++){
if (data.charCodeAt(i+startIndex) > 128)
{
j = j - 1
}
}
return j;
}
mx_internal static function stringBCLenght(data:ByteArray, from:uint = 0, len:uint = 0):int
{
var i:uint;
var j:uint = len;
var startIndex:uint = from + 4 + len.toString().length;
for (i = 0; i < j; i++){
if (Serializer.charCodeAt(data, i+startIndex) > 128)
{
j = j - 1
}
}
return j;
}
mx_internal static function stringLength(data:String):uint
{
var code:int = 0
var result:int = 0
var slen:int = data.length;
while(slen){
slen = slen - 1
try
{
code = data.charCodeAt(slen)
} catch(e:Error){
code = 65536
}
if(code < 128){
result = result + 1
} else if(code < 2048){
result = result + 2
} else if(code < 65536){
result = result + 3
} else {
result = result + 4
}
}
return result
}
public static function charAt(bytes:ByteArray, index:int):String {
if (bytes.length <= index) return null;
return String.fromCharCode(bytes[index]);
}
public static function charCodeAt(bytes:ByteArray, index:int):int {
if (bytes.length <= index) return -1;
return bytes[index];
}
public static function substr(bytes:ByteArray, start:int, length:int=0):ByteArray {
var res:ByteArray = new ByteArray();
bytes.position = start;
bytes.readBytes(res, 0, length);
return res;
}
public static function substring(bytes:ByteArray, start:int, end:int=0):ByteArray {
return substr(bytes, start, end-start);
}
public static function indexOf(bytes:ByteArray, str:String, startIndex:int):int {
var num:int = 0;
for (var i:int=0; i<bytes.length; i++) {
var strPos:int = 0;
while (bytes[i+strPos] == str.charCodeAt(strPos)) {
strPos++;
if (strPos == str.length) {
num++;
if(num == startIndex) {
return i;
}
}
}
}
return -1;
}
}
}
I resolved the issue, no need for answers.
Related
I've got a Laravel project but I think I have an idea of how to incorporate the Dynamic Web Twain (https://www.dynamsoft.com/Products/WebTWAIN_Overview.aspx) into it.
The only problem is I'm not quite sure how I would go about adding additional fields to the scanner UI (like what you see here: https://demo.dynamsoft.com/dwt/online_demo_scan.aspx).
At the moment my Laravel site has a working upload portion to a model where I can submit attachments, however, with the attachment form are fields that include "visibility", "type", "upload location" etc. etc. But I can't seem to figure out how I would add fields like what I already use.
From what I've tested, this is an incredibly useful tool and would work well if I could integrate it into all aspects of my site.
The closest thing I can find is here: https://developer.dynamsoft.com/dwt/api-reference/uploading-downloading/sethttpformfield
Which references what is done in this demo: https://demo.dynamsoft.com/Samples/dwt/Scan-Documents-and-Upload-Them/DWT_Scan_Upload_Demo.html
As you can see, you can add a field name and field value, using the "+" button, but I want to add some fields in the form that are available immediately. The other issue that I might need to work around is if I use this demo and add a value and name, this is how everything is posted and I'm not sure how to translate to something my project can understand.
-----------------------------23491353817351
Content-Disposition: form-data; name="This is a field"
Wow
-----------------------------23491353817351
Content-Disposition: form-data; name="RemoteFile"; filename="507-0.jpg"
Content-Type: application/octet-stream
ÿØÿà
This aspect is a necessary part of my project, so unfortunately there's no real way around this besides moving forward.
This is the current script in the online demo:
Dynamsoft.WebTwainEnv.RegisterEvent('OnWebTwainReady', Dynamsoft_OnReady); // Register OnWebTwainReady event. This event fires as soon as Dynamic Web TWAIN is initialized and ready to be used
var DWObject, blankField = "", extrFieldsCount = 0, upload_returnSth = true;
var CurrentPathName = unescape(location.pathname);
var CurrentPath = CurrentPathName.substring(0, CurrentPathName.lastIndexOf("/") + 1);
var strHTTPServer = location.hostname;
var strActionPage;
var scriptLanguages = [
{ desc: "PHP", val: "php" },
{ desc: "PHP-MySQL", val: "phpMySQL" },
{ desc: "CSharp", val: "csharp" },
{ desc: "CSharp-MSSQL", val: "csMSSQL" },
{ desc: "VB.NET", val: "vbnet" },
{ desc: "VBNET-MSSQL", val: "vbnetMSSQL" },
{ desc: "JSP", val: "jsp" },
{ desc: "JSP-Oracle", val: "jspOracle" },
{ desc: "ASP", val: "asp" },
{ desc: "ASP-MSSQL", val: "aspMSSQL" },
{ desc: "ColdFusion", val: "cfm" },
{ desc: "CS-Azure", val: "csAzure" }
];
function languageSelected() {
if (document.getElementById("ddlLanguages").selectedIndex > 7)
upload_returnSth = false;
else
upload_returnSth = true;
if ([0, 2, 4, 6].indexOf(document.getElementById("ddlLanguages").selectedIndex) == -1) {
document.getElementById("extra-fields-div-id").style.display = 'none';
document.getElementById('div-extra-fields').style.display = 'none';
}
else {
document.getElementById("extra-fields-div-id").style.display = '';
if (document.getElementById('div-extra-fields').children.length > 1 ||
document.getElementById('div-extra-fields').children[0].children[0].value != '') {
document.getElementById('div-extra-fields').style.display = '';
}
}
}
function addAField() {
extrFieldsCount++;
if (extrFieldsCount == 3) {
document.getElementById('div-extra-fields').style.overflowY = 'scroll';
}
if (document.getElementById('div-extra-fields').style.display == "none")
document.getElementById('div-extra-fields').style.display = '';
else {
document.getElementById('div-extra-fields').appendChild(blankField);
blankField = document.getElementsByClassName('div-fields-item')[extrFieldsCount - 1].cloneNode(true);
}
}
function downloadPDFR() {
DCP_DWT_OnClickCloseInstall();
DWObject.Addon.PDF.Download(
CurrentPath + '/Resources/addon/Pdf.zip',
function () {/*console.log('PDF dll is installed');*/
},
function (errorCode, errorString) {
console.log(errorString);
}
);
}
function Dynamsoft_OnReady() {
blankField = document.getElementsByClassName('div-fields-item')[0].cloneNode(true);
DWObject = Dynamsoft.WebTwainEnv.GetWebTwain('dwtcontrolContainer'); // Get the Dynamic Web TWAIN object that is embeded in the div with id 'dwtcontrolContainer'
if (DWObject) {
DWObject.Width = 505;
DWObject.Height = 600;
for (var i = 0; i < scriptLanguages.length; i++)
document.getElementById("ddlLanguages").options.add(new Option(scriptLanguages[i].desc, i));
document.getElementById("ddlLanguages").options.selectedIndex = 2;
/*
* Make sure the PDF Rasterizer and OCR add-on are already installedsample
*/
if (!Dynamsoft.Lib.env.bMac) {
var localPDFRVersion = '';
if(Dynamsoft.Lib.product.bChromeEdition){
localPDFRVersion = DWObject._innerFun('GetAddOnVersion', '["pdf"]');
}
else {
localPDFRVersion = DWObject.getSWebTwain().GetAddonVersion("pdf");
}
if (localPDFRVersion != Dynamsoft.PdfVersion) {
var ObjString = [];
ObjString.push('<div class="p15" id="pdfr-install-dlg">');
ObjString.push('The <strong>PDF Rasterizer</strong> is not installed on this PC<br />Please click the button below to get it installed');
ObjString.push('<p class="tc mt15 mb15"><input type="button" value="Install PDF Rasterizer" onclick="downloadPDFR();" class="btn lgBtn bgBlue" /><hr></p>');
ObjString.push('<i><strong>The installation is a one-time process</strong> <br />It might take some time depending on your network.</i>');
ObjString.push('</div>');
Dynamsoft.WebTwainEnv.ShowDialog(400, 310, ObjString.join(''));
}
else {
/**/
}
}
}
}
function AcquireImage() {
if (DWObject) {
var bSelected = DWObject.SelectSource();
if (bSelected) {
var OnAcquireImageSuccess, OnAcquireImageFailure;
OnAcquireImageSuccess = OnAcquireImageFailure = function () {
DWObject.CloseSource();
};
DWObject.OpenSource();
DWObject.IfDisableSourceAfterAcquire = true; //Scanner source will be disabled/closed automatically after the scan.
DWObject.AcquireImage(OnAcquireImageSuccess, OnAcquireImageFailure);
}
}
}
function LoadImages() {
if (DWObject) {
DWObject.Addon.PDF.SetResolution(300);
DWObject.Addon.PDF.SetConvertMode(EnumDWT_ConverMode.CM_RENDERALL);
DWObject.LoadImageEx('', 5,
function () {
},
function (errorCode, errorString) {
alert('Load Image:' + errorString);
}
);
}
}
function OnHttpUploadSuccess() {
console.log('successful');
}
function OnHttpServerReturnedSomething(errorCode, errorString, sHttpResponse) {
//console.log(errorString);
var textFromServer = sHttpResponse;
_printUploadedFiles(textFromServer);
}
function _printUploadedFiles(info) {
//console.log(info);
if (info.indexOf('DWTUploadFileName') != -1) {
var url, _strPort;
DWObject.IfSSL = Dynamsoft.Lib.detect.ssl;
_strPort = location.port == "" ? 80 : location.port
url = 'http://' + location.hostname + ':' + location.port
if (Dynamsoft.Lib.detect.ssl == true) {
_strPort = location.port == "" ? 443 : location.port;
url = 'https://' + location.hostname + ':' + location.port
}
var savedIntoToDB = false, imgIndexInDB = "-1";
if (info.indexOf("DWTUploadFileIndex:") != -1) {
savedIntoToDB = true;
imgIndexInDB = info.substring(info.indexOf('DWTUploadFileIndex') + 19, info.indexOf('DWTUploadFileName'));
//console.log(imgIndexInDB);
}
var fileName = info.substring(info.indexOf('DWTUploadFileName') + 18, info.indexOf('UploadedFileSize'));
var fileSize = info.substr(info.indexOf('UploadedFileSize') + 17);
if (savedIntoToDB) {
if (info.indexOf('CSHARP') != -1) {
url += CurrentPath + 'action/csharp-db.aspx?imgID=' + imgIndexInDB;
}
else if (info.indexOf('VBNET') != -1) {
url += CurrentPath + 'action/vbnet-db.aspx?imgID=' + imgIndexInDB;
}
else if (info.indexOf('PHP') != -1) {
url += CurrentPath + 'action/php-mysql.php?imgID=' + imgIndexInDB;
}
else if (info.indexOf('JSP') != -1) {
url += CurrentPath + 'action/jsp-oracle.jsp?imgID=' + imgIndexInDB;
}
}
else {
url += CurrentPath + 'action/UploadedImages/' + encodeURI(fileName);
}
var newTR = document.createElement('tr');
_str = "<td class='tc'><a class='bluelink'" + ' href="' + url + '" target="_blank">' + fileName + "</a></td>"
+ "<td class='tc'>" + fileSize + '</td>';
if (info.indexOf("FieldsTrue:") != -1)
_str += "<td class='tc'><a class='bluelink'" + '" href="' + url.substring(0, url.length - 4) + '_1.txt' + '" target="_blank">Fields</td>';
else {
_str += "<td class='tc'>No Fields</td>";
}
newTR.innerHTML = _str;
document.getElementById('div-uploadedFile').appendChild(newTR);
}
}
function upload_preparation(_name) {
DWObject.IfShowCancelDialogWhenImageTransfer = !document.getElementById('quietScan').checked;
strActionPage = CurrentPath + 'action/';
switch (document.getElementById("ddlLanguages").options.selectedIndex) {
case 0: strActionPage += "php.php"; break;
case 2: strActionPage += "csharp.aspx"; break;
case 6: strActionPage += "jsp.jsp"; break;
case 4: strActionPage += "vbnet.aspx"; break;
case 8: strActionPage += "asp.asp"; break;
case 10: strActionPage += "cfm.cfm"; break;
case 1: strActionPage += "php-mysql.php?imgID=new"; break;
case 7: strActionPage += "jsp-oracle.jsp?imgID=new"; break;
case 3: strActionPage += "csharp-db.aspx?imgID=new"; break;
case 5: strActionPage += "vbnet-db.aspx?imgID=new"; break;
case 9: strActionPage += "asp-db.asp"; break;
case 11: preparetoUploadtoAzure(_name); break;
default: break;
}
DWObject.IfSSL = Dynamsoft.Lib.detect.ssl;
var _strPort = location.port == "" ? 80 : location.port;
if (Dynamsoft.Lib.detect.ssl == true)
_strPort = location.port == "" ? 443 : location.port;
DWObject.HTTPPort = _strPort;
if ([0, 2, 4, 6].indexOf(document.getElementById("ddlLanguages").selectedIndex) != -1) {
/* Add Fields to the Post */
var fields = document.getElementsByClassName('div-fields-item');
DWObject.ClearAllHTTPFormField();
for (var n = 0; n < fields.length; n++) {
var o = fields[n];
if (o.children[0].value != '')
DWObject.SetHTTPFormField(o.children[0].value, o.children[1].value);
}
}
}
function UploadImage_inner() {
if (DWObject.HowManyImagesInBuffer == 0)
return;
var Digital = new Date();
var uploadfilename = Digital.getMilliseconds(); // Uses milliseconds according to local time as the file name
upload_preparation(uploadfilename);
// Upload the image(s) to the server asynchronously
if (document.getElementById("ddlLanguages").options.selectedIndex == 11 /*Azure*/) return;
if (document.getElementsByName('ImageType')[0].checked) {
var uploadIndexes = [];
for (var i = DWObject.HowManyImagesInBuffer - 1; i > -1 ; i--) {
uploadIndexes.push(i);
}
var uploadJPGsOneByOne = function (errorCode, errorString, sHttpResponse) {
if (upload_returnSth)
_printUploadedFiles(sHttpResponse);
if (uploadIndexes.length > 0) {
var _index = uploadIndexes.pop();
if (upload_returnSth)
DWObject.HTTPUploadThroughPost(strHTTPServer, _index, strActionPage, uploadfilename + "-" + _index.toString() + ".jpg", OnHttpUploadSuccess, uploadJPGsOneByOne);
else
DWObject.HTTPUploadThroughPost(strHTTPServer, _index, strActionPage, uploadfilename + "-" + _index.toString() + ".jpg", uploadJPGsOneByOne, OnHttpServerReturnedSomething);
}
}
var _index = uploadIndexes.pop();
if (upload_returnSth)
DWObject.HTTPUploadThroughPost(strHTTPServer, _index, strActionPage, uploadfilename + "-" + _index.toString() + ".jpg", OnHttpUploadSuccess, uploadJPGsOneByOne);
else
DWObject.HTTPUploadThroughPost(strHTTPServer, _index, strActionPage, uploadfilename + "-" + _index.toString() + ".jpg", uploadJPGsOneByOne, OnHttpServerReturnedSomething);
}
else if (document.getElementsByName('ImageType')[1].checked) {
DWObject.HTTPUploadAllThroughPostAsMultiPageTIFF(strHTTPServer, strActionPage, uploadfilename + ".tif", OnHttpUploadSuccess, OnHttpServerReturnedSomething);
}
else if (document.getElementsByName('ImageType')[2].checked) {
DWObject.HTTPUploadAllThroughPostAsPDF(strHTTPServer, strActionPage, uploadfilename + ".pdf", OnHttpUploadSuccess, OnHttpServerReturnedSomething);
}
}
function UploadImage() {
if (DWObject) {
var nCount = 0, nCountUpLoaded = 0, aryFilePaths = [];
if (document.getElementById('uploadDirectly').checked) {
DWObject.IfShowCancelDialogWhenImageTransfer = false;
function ds_load_file_to_upload_directly(bSave, filesCount, index, path, filename) {
nCount = filesCount;
var filePath = path + "\\" + filename;
aryFilePaths.push(filePath);
if (aryFilePaths.length == nCount) {
upload_preparation();
var i = 0;
function uploadFileOneByOne() {
DWObject.HTTPUploadThroughPostDirectly(strHTTPServer, filePath, strActionPage, filename,
function () {
console.log('Upload Image:' + aryFilePaths[i] + ' -- successful');
i++;
if (i != nCount)
uploadFileOneByOne();
else
DWObject.UnregisterEvent('OnGetFilePath', ds_load_file_to_upload_directly);
},
OnHttpServerReturnedSomething
);
}
uploadFileOneByOne();
}
}
DWObject.RegisterEvent('OnGetFilePath', ds_load_file_to_upload_directly);
DWObject.ShowFileDialog(false, "Any File | *.*", 0, "", "", true, true, 0);
}
else {
UploadImage_inner();
}
}
}
/*******************/
/* Upload to Azure */
var Base64Binary = {
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
decode: function (input, arrayBuffer) {
//get last chars to see if are valid
var lkey1 = this._keyStr.indexOf(input.charAt(input.length - 1));
var lkey2 = this._keyStr.indexOf(input.charAt(input.length - 2));
var bytes = (input.length / 4) * 3;
if (lkey1 == 64) bytes--; //padding chars, so skip
if (lkey2 == 64) bytes--; //padding chars, so skip
var uarray;
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
var j = 0;
if (arrayBuffer)
uarray = new Uint8Array(arrayBuffer);
else
uarray = new Uint8Array(bytes);
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
for (i = 0; i < bytes; i += 3) {
//get the 3 octects in 4 ascii chars
enc1 = this._keyStr.indexOf(input.charAt(j++));
enc2 = this._keyStr.indexOf(input.charAt(j++));
enc3 = this._keyStr.indexOf(input.charAt(j++));
enc4 = this._keyStr.indexOf(input.charAt(j++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
uarray[i] = chr1;
if (enc3 != 64) uarray[i + 1] = chr2;
if (enc4 != 64) uarray[i + 2] = chr3;
}
return uarray;
}
}
function uploadImageInner_azure(blobSasUrl, fileDataAsArrayBuffer) {
var ajaxRequest = new XMLHttpRequest();
try {
ajaxRequest.open('PUT', blobSasUrl, true);
ajaxRequest.setRequestHeader('x-ms-blob-type', 'BlockBlob');
ajaxRequest.send(fileDataAsArrayBuffer);
ajaxRequest.onreadystatechange = function () {
if (ajaxRequest.readyState == 4) {
console.log('Upload image to azure server successfully.');
}
}
}
catch (e) {
console.log("can't upload the image to server.\n" + e.toString());
}
}
function preparetoUploadtoAzure(__name) {
var uploadfilename = '';
//For JPEG, upload the current image
if (document.getElementsByName('ImageType')[0].checked) {
DWObject.SelectedImagesCount = 1;
DWObject.SetSelectedImageIndex(0, DWObject.CurrentImageIndexInBuffer);
DWObject.GetSelectedImagesSize(EnumDWT_ImageType.IT_JPG);
uploadfilename = __name + '.jpg';
}
else { //For TIFF, PDF, upload all images
var count = DWObject.HowManyImagesInBuffer;
DWObject.SelectedImagesCount = count;
for (var i = 0; i < count; i++) {
DWObject.SetSelectedImageIndex(i, i);
}
if (document.getElementsByName('ImageType')[1].checked) {
DWObject.GetSelectedImagesSize(EnumDWT_ImageType.IT_TIF);
uploadfilename = __name + '.tif';
}
else {
DWObject.GetSelectedImagesSize(EnumDWT_ImageType.IT_PDF);
uploadfilename = __name + '.pdf';
}
}
var strImg, aryImg, _uint8_STR, _bin_ARR, _blobImg;
strImg = DWObject.SaveSelectedImagesToBase64Binary();
// convert base64 to Uint8Array
var bytes = (strImg.length / 4) * 3;
var _temp = new ArrayBuffer(bytes);
_uint8_STR = Base64Binary.decode(strImg, _temp);
// convert Uint8Array to blob
_blobImg = new Blob([_uint8_STR]);
// upload to Azure server
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
uploadImageInner_azure(xhr.responseText, _blobImg);
}
}
var actionPageFullPath = CurrentPath + 'action/' + 'azure.aspx?imageName=' + uploadfilename;
xhr.open('GET', actionPageFullPath, true);
xhr.send();
}
/*******************/
I want to make an auto-increment alphanumeric and this is just for output
if i press a button , there is an output AA001 and then i press a button again there is an output AA002
This doesn't use any 'clever' tricks but is shorter and easier to understand and tweak. It also uses numbers so it doesn't grow the length of the string as quickly. It increments from 0-9 then a-z, but it is intended that you should feed in 'a' to start with. Output always starts with an alphabet character, as long as your input also starts with an alphabet character, so it can be used as PHP variable names
var nextVarName = function(str) {
// Position of char to change.
var change = str.length - 1;
// The value of that char.
var change_char = str[change];
// Number of zeros to append when flipping.
var zeros = 0;
// Iterate backwards while there's a z (flipping).
while (change_char == 'z') {
// Increase the length of appended zeros
zeros++;
// Move the char to change back.
change_char = str[--change];
}
if (change_char == undefined) {
// Full flip - string increases in length.
str = 'a' + Array(str.length + 1).join("0");
} else {
// Normal increment with partial flip and 9->a handling.
str = str.substr(0, change)
+ (change_char == '9' ? 'a' : String.fromCharCode(str.charCodeAt(change) + 1))
+ Array(zeros + 1).join('0');
}
return str;
};
var vname = 'a';
for (var i = 0; i < 5; i++) {
vname = nextVarName(vname);
console.log(vname);
}
The results will be as follows:
z ---> a0
9z ---> a0 (unexpected input)
ab1zde ---> ab1zdf
abcdzz ---> abce00
zzzzz ---> a00000
abcyzz ---> abcz00
9000 ---> 9001 (unexpected input)
https://jsfiddle.net/e20kfvky/
The schedule of how many variables (that start with an alphabet char) are created of each length is as follows:
1: 26, 2: 936, 3: 33696, 4: 1213056 ... n: 36 ^ n - 10 * 36 ^ (n - 1)
The following code will generate a token that you can advance by one. It uses some small classes to make it modular. The function you attach to the button will call the function next on the token as shown in the very bottom.
//Element in a big token
function Increment(startval, endval) {
this.start = startval.charCodeAt(0);
this.cur = this.start;
this.end = endval.charCodeAt(0);
//Returns the current value
this.get = function() {
if (this.cur <= this.end) {
return String.fromCharCode(this.cur);
} else {
return null;
}
}
//Advances the value we will show
this.next = function() {
this.cur += 1;
return this.get();
}
//Reset it to the beginning
this.reset = function() {
this.cur = this.start;
}
}
function Token() {
this.token = [
new Increment("A", "Z"),
new Increment("A", "Z"),
new Increment("0", "9"),
new Increment("0", "9"),
new Increment("0", "9")
];
this.get = function() {
return this.token.map(function(cur) {
return cur.get();
}).join("");
}
this.next = function() {
//From the back to the front
for (var i = this.token.length - 1; i >= 0; i--) {
if (this.token[i].next() == null) {
//If we exhausted all possible values, continue
this.token[i].reset();
} else {
//Until we advance one that has still values left
break;
}
}
return this.get();
}
}
//Now we are just showing off...
var a = new Token();
for (var i = 0; i < 15; i++) {
console.log(a.next());
}
const getNextAlphaString = function (str) {
"use strict";
str=str.toUpperCase();
let chars;
chars = str.split("");
const strLen = str.length;
let continueIncermenting = true;
for (let i = strLen - 1; i >= 0; i = i - 1) {
let asciiVal;
asciiVal = chars[i].charCodeAt(0);
if (isNaN(asciiVal)) {
return str;
}
if (continueIncermenting === true) {
if (asciiVal >= 48 && asciiVal < 57) {
chars[i] = String.fromCharCode(asciiVal + 1);
continueIncermenting = false;
break;
} else if (asciiVal == 57) {
chars[i] = '0';
continueIncermenting = true;
}
if (asciiVal >= 65 && asciiVal < 90) {
chars[i] = String.fromCharCode(asciiVal + 1);
continueIncermenting = false;
break;
} else if (asciiVal == 90) {
chars[i] = String.fromCharCode(65);
continueIncermenting = true;
}
} else {
if (asciiVal == 90) {
continueIncermenting = true;
chars[i] = String.fromCharCode(65);
}
if (asciiVal == 57) {
continueIncermenting = true;
chars[i] = '0';
}
}
}
if (continueIncermenting === true) {
let firstAcii = chars[0].charCodeAt(0);
if (isNaN(firstAcii)) {
return str;
}
if ((firstAcii >= 65 && firstAcii <= 90) || (firstAcii >= 97 && firstAcii <= 122)) {
return 'A' + chars.join('').toUpperCase();
}
if (firstAcii >= 48 && firstAcii <= 57) {
return '0' + chars.join('').toUpperCase();
}
}
return chars.join('').toUpperCase();
};
The results will be as follows:
ab1zde ---> AB1ZDF
abcdzz ---> ABCEAA
zzzzz ---> AAAAAA
abcyzz ---> ABCZAA
9000 ---> 9001
I am wondering if there is a rot5 function for PHP equalivant too
function rot5(str) {
var s = [];
for (i = 0; i < str.length; i ++)
{
idx = str.charCodeAt(i);
if ((idx >= 48) && (idx <= 57))
{
if (idx <= 52)
{
s[i] = String.fromCharCode(((idx + 5)));
}
else
{
s[i] = String.fromCharCode(((idx - 5)));
}
}
else
{
s[i] = String.fromCharCode(idx);
}
}
return s.join('');
}
In javascript? If not then how can I do fromCharCode and charCodeAt in PHP?
Here you got generic strrot with default to strrot5
<?php
function strrot($str, $n=5){
$replace = [];
for($i=0;$i<26;$i++){
$replace[chr(65+$i)] = chr(65+(($i+$n)%26));
$replace[chr(97+$i)] = chr(97+(($i+$n)%26));
}
return strtr($str, $replace);
}
You can use 'ord' for 'charCodeAt'.
ord($yourstring[$yourindex])
You can use 'chr' for 'fromCharCode'
chr($yourcharcode)
I've got a Problem with converting a JS-based RSA File into PHP.
JavaScript:
Main File:
var RSAPublicKey = function($modulus_hex, $encryptionExponent_hex) {
this.modulus = new BigInteger( $modulus_hex, 16);
this.encryptionExponent = new BigInteger( $encryptionExponent_hex, 16);
}
var Base64 = {
base64: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
encode: function($input) {
if (!$input) {
return false;
}
var $output = "";
var $chr1, $chr2, $chr3;
var $enc1, $enc2, $enc3, $enc4;
var $i = 0;
do {
$chr1 = $input.charCodeAt($i++);
$chr2 = $input.charCodeAt($i++);
$chr3 = $input.charCodeAt($i++);
$enc1 = $chr1 >> 2;
$enc2 = (($chr1 & 3) << 4) | ($chr2 >> 4);
$enc3 = (($chr2 & 15) << 2) | ($chr3 >> 6);
$enc4 = $chr3 & 63;
if (isNaN($chr2)) $enc3 = $enc4 = 64;
else if (isNaN($chr3)) $enc4 = 64;
$output += this.base64.charAt($enc1) + this.base64.charAt($enc2) + this.base64.charAt($enc3) + this.base64.charAt($enc4);
} while ($i < $input.length);
return $output;
},
decode: function($input) {
if(!$input) return false;
$input = $input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
var $output = "";
var $enc1, $enc2, $enc3, $enc4;
var $i = 0;
do {
$enc1 = this.base64.indexOf($input.charAt($i++));
$enc2 = this.base64.indexOf($input.charAt($i++));
$enc3 = this.base64.indexOf($input.charAt($i++));
$enc4 = this.base64.indexOf($input.charAt($i++));
$output += String.fromCharCode(($enc1 << 2) | ($enc2 >> 4));
if ($enc3 != 64) $output += String.fromCharCode((($enc2 & 15) << 4) | ($enc3 >> 2));
if ($enc4 != 64) $output += String.fromCharCode((($enc3 & 3) << 6) | $enc4);
} while ($i < $input.length);
return $output;
}
};
var Hex = {
hex: "0123456789abcdef",
encode: function($input) {
if(!$input) return false;
var $output = "";
var $k;
var $i = 0;
do {
$k = $input.charCodeAt($i++);
$output += this.hex.charAt(($k >> 4) &0xf) + this.hex.charAt($k & 0xf);
} while ($i < $input.length);
return $output;
},
decode: function($input) {
if(!$input) return false;
$input = $input.replace(/[^0-9abcdef]/g, "");
var $output = "";
var $i = 0;
do {
$output += String.fromCharCode(((this.hex.indexOf($input.charAt($i++)) << 4) & 0xf0) | (this.hex.indexOf($input.charAt($i++)) & 0xf));
} while ($i < $input.length);
return $output;
}
};
var RSA = {
getPublicKey: function( $modulus_hex, $exponent_hex ) {
return new RSAPublicKey( $modulus_hex, $exponent_hex );
},
encrypt: function($data, $pubkey) {
if (!$pubkey) return false;
$data = this.pkcs1pad2($data,($pubkey.modulus.bitLength()+7)>>3);
if(!$data) return false;
$data = $data.modPowInt($pubkey.encryptionExponent, $pubkey.modulus);
if(!$data) return false;
$data = $data.toString(16);
return Base64.encode(Hex.decode($data));
},
pkcs1pad2: function($data, $keysize) {
if($keysize < $data.length + 11)
return null;
var $buffer = [];
var $i = $data.length - 1;
while($i >= 0 && $keysize > 0)
$buffer[--$keysize] = $data.charCodeAt($i--);
$buffer[--$keysize] = 0;
while($keysize > 2)
$buffer[--$keysize] = Math.floor(Math.random()*254) + 1;
$buffer[--$keysize] = 2;
$buffer[--$keysize] = 0;
return new BigInteger($buffer);
}
}
How I use it:
var pubKey = RSA.getPublicKey( results.publickey_mod, results.publickey_exp );
var encryptedPassword = RSA.encrypt( form.elements['password'].value, pubKey );
Now I want to convert this into PHP, thing I have tried so far:
$pkey = $json["publickey_mod"];
$rsa = new Crypt_RSA();
$rsa->loadKey($pkey);
$rsa->exponent = $json["publickey_exp"];
echo ($rsa->setPublicKey($pkey))?"success":"fail";
$plain = "text";
echo $rsa->encrypt($plain);
But it always prints a "fail", what's wrong with it?
How the Key looks like:
CD5D11DFC04D457B864421AA483118EEA3A96C97E01ABFA4BAD356EC3CE6CA7E3F61665BAA1322D1D6C763D4463C1B41D69397281538D22302D8817CC10AEBDA96970DA4BA46BA79808E3B7BC3D38C1C2FD746E73EA5907F07C9588A1AF2C337FED1B7C8BB29304035420FB7EDE92511D1B07A63E21A5C36F132B556EE879113E88395ACCE9B987E478F8EA11B34634BCDA863DE7045EA9D7AB3240F406C572F36FDE1DB1534F92022B91DFBE23F980D0190D69953037EF9F38F98DA1A8028BE009CE82B979E8E427305802330111A78737D8E11C9CB132170CB34618941FA2AC2C754338886BFEE7DAD779036B292F9711DD9C765F37D42B6C0DC0BCCC83765
I know this is a bit old lol but it looks like you're using PKCS#1 padding. phpseclib uses OAEP padding by default. Try doing this:
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
PHP Function:
function formatNumberForDisplay($number, $decimal=0, $decimalSeperator='.', $numberSeperator=',')
{
return number_format($number, $decimal, $decimalSeperator, $numberSeperator);
}
Can anybody suggest to me the equivalent functionality in jQuery/JavaScript?
The same equivalent of number_format in js can found here
function number_format (number, decimals, dec_point, thousands_sep) {
// Strip all characters but numerical ones.
number = (number + '').replace(/[^0-9+\-Ee.]/g, '');
var n = !isFinite(+number) ? 0 : +number,
prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
s = '',
toFixedFix = function (n, prec) {
var k = Math.pow(10, prec);
return '' + Math.round(n * k) / k;
};
// Fix for IE parseFloat(0.55).toFixed(0) = 0;
s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
if (s[0].length > 3) {
s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
}
if ((s[1] || '').length < prec) {
s[1] = s[1] || '';
s[1] += new Array(prec - s[1].length + 1).join('0');
}
return s.join(dec);
}
Just use toLocaleString on an integer object.
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString#Browser_compatibility
let x = 1234567;
//if x is a string/non-number, use parseInt/parseFloat to convert to a number. Thanks #Aleksandr Kopelevich
x.toLocaleString('us', {minimumFractionDigits: 2, maximumFractionDigits: 2})
is this what you'd like to get?
yourFloatVarHere.toFixed(2);
voilà.
Native "Intl" object approach:
var amount = 5000.25;
var locale = 'de';
var options = {style: 'currency', currency: 'eur', minimumFractionDigits: 2, maximumFractionDigits: 2};
var formatter = new Intl.NumberFormat(locale, options);
console.log(formatter.format(amount));
http://jsfiddle.net/arturrelax/sa9jL138/1/
More information at: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl
I know it's an old thread, but I made my own function, which is in pure Javascript.
Simple Solution
https://gist.github.com/VassilisPallas/d73632e9de4794b7dd10b7408f7948e8/bf17eccef8521b4e5869bdc6a5b09a771356fbff
This works fine with finite numbers
function number_format(number, decimals, dec_point, thousands_point) {
if (number == null || !isFinite(number)) {
throw new TypeError("number is not valid");
}
if (!decimals) {
var len = number.toString().split('.').length;
decimals = len > 1 ? len : 0;
}
if (!dec_point) {
dec_point = '.';
}
if (!thousands_point) {
thousands_point = ',';
}
number = parseFloat(number).toFixed(decimals);
number = number.replace(".", dec_point);
var splitNum = number.split(dec_point);
splitNum[0] = splitNum[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousands_point);
number = splitNum.join(dec_point);
return number;
}
Complex Solution
This solves the issue with big numbers
https://gist.github.com/VassilisPallas/d73632e9de4794b7dd10b7408f7948e8
const splitThousands = (number) => (dec_point, thousands_point) => {
const splitNum = number.toString().split(dec_point);
splitNum[0] = splitNum[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousands_point);
return splitNum.join(dec_point);
};
const isBigNumber = (number) => number.toString().includes("e");
const isBigFloat = (number) => number.toString().includes("-");
const calcTrailing = (dec, len) => Number(dec) + 2 - len;
const handleBigFloats = (number, decimals) => {
if (!decimals) {
return "0";
}
const [numbers, dec] = number.toString().replace(".", "").split("e-");
const trailingZeros = calcTrailing(dec, numbers.length);
const res = `${"0.".padEnd(trailingZeros + 2, "0")}${numbers}`;
return decimals ? res.substring(0, 2) + res.substring(2, decimals + 2) : res;
};
const handleBigNumbers = (number, decimals, dec_point, thousands_point) => {
if (isBigFloat(number)) {
return handleBigFloats(number, decimals);
}
return splitThousands(BigInt(number))(dec_point, thousands_point);
};
function handleFiniteNumbers(number, decimals, dec_point, thousands_point) {
if (!isFinite(number)) {
throw new TypeError("number is not finite number");
}
if (!decimals) {
const len = number.toString().split(".").length;
decimals = len > 1 ? len : 0;
}
return splitThousands(
parseFloat(number).toFixed(decimals).replace(".", dec_point)
)(dec_point, thousands_point);
}
const numberFormat = (
number,
decimals,
dec_point = ".",
thousands_point = ","
) => {
if (number == null || typeof number !== "number") {
throw new TypeError("number is not valid");
}
if (isBigNumber(number)) {
return handleBigNumbers(number, decimals, dec_point, thousands_point);
}
return handleFiniteNumbers(number, decimals, dec_point, thousands_point);
};
https://jsfiddle.net/p2ft9n4v/1/
Closer function to php number_format($number) should be number.toLocaleString('en') of javascript
Here is another short solution that should behaviour like the php-equivalent.
function number_format(number,decimals,dec_point,thousands_sep) {
number = number*1;//makes sure `number` is numeric value
var str = number.toFixed(decimals?decimals:0).toString().split('.');
var parts = [];
for ( var i=str[0].length; i>0; i-=3 ) {
parts.unshift(str[0].substring(Math.max(0,i-3),i));
}
str[0] = parts.join(thousands_sep?thousands_sep:',');
return str.join(dec_point?dec_point:'.');
}
Here is a simple function that you can use to achieve almost the same result of number_format in php:
function number_format(user_input){
var filtered_number = user_input.replace(/[^0-9]/gi, '');
var length = filtered_number.length;
var breakpoint = 1;
var formated_number = '';
for(i = 1; i <= length; i++){
if(breakpoint > 3){
breakpoint = 1;
formated_number = ',' + formated_number;
}
var next_letter = i + 1;
formated_number = filtered_number.substring(length - i, length - (i - 1)) + formated_number;
breakpoint++;
}
return formated_number;
}
Another way is to use ajax to make a call to a php script where you run number_format on the number and return it with ajax as a string. But it`s a bit messy.
It no easy, try to use simple jquery-plugins such as:
jquery-numberformatter
Jquery-Price-Format
My take on this:
var number_format = function(num) {
stringNum = num.toString();
stringNum = stringNum.split("");
c = 0;
if (stringNum.length>3) {
for (i=stringNum.length; i>-1; i--) {
if ( (c==3) && ((stringNum.length-i)!=stringNum.length) ) {
stringNum.splice(i, 0, ",");
c=0;
}
c++
}
return stringNum;
}
return num;
}
$("body").append(number_format(100000000));
Another variant of exposed examples:
const numberFormat = (value, decimals, decPoint, thousandsSep) => {
decPoint = decPoint || '.';
decimals = decimals !== undefined ? decimals : 2;
thousandsSep = thousandsSep || ' ';
if (typeof value === 'string') {
value = parseFloat(value);
}
let result = value.toLocaleString('en-US', {
maximumFractionDigits: decimals,
minimumFractionDigits: decimals
});
let pieces = result.split('.');
pieces[0] = pieces[0].split(',').join(thousandsSep);
return pieces.join(decPoint);
};
The JS equivalent will be:
var number = //input value
parseFloat(number).toFixed(3);
I'm to do it just calling the JS function as follows and it works:
var formattedNumber = number_format(value)