I use a random string generator, based on this:
http://stackoverflow.com/questions/1344221/how-can-i-generate-random-8-character-alphanumeric-strings-in-c
Every now and then, it will generate a 20 chars len string like this
aaaaaaaaaaaaaaaaaaaa when it needs to generate a 20 chars len string full of random chars (eg 63TSRVvbVDJiMNwneB5l), like if the C# Random object would return a value of 0 every time over the 20 iterations.
public static string GetRandomAlphaNumericString(int charCount)
{
var result = new string(
Enumerable.Repeat(CHARS, charCount)
.Select(s =>
{
var nxt = SHARED_RANDOM.Next(s.Length);
var rval = s[nxt];
return rval;
})
.ToArray());
return result;
}
const string CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
public static Random SHARED_RANDOM = new Random(Guid.NewGuid().GetHashCode());
It doesn't make sense to me, what could I be overseeing in this generator ? The generator works OK, but every now and then, very rarely, it would perform like this generating a strike aaaaaaa strings for a short period of time.
I don't see a bug in the code, so to me it's 1 of 2 things, or the C# Random object is acting funny in some situations, returning 0 for a short period of time, or the CHARS const string changes from "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" to "a" in the assembly for some reason, for a short period of time.
I can't believe it could be either of the above, I prefer to believe that I'm overseeing something. Do you see or imagine how could this possibly be happening ?
UPDATE OCT 23 / 2017
Coded a test routine so if the GetRandomAlphaNumericString produces the evil aaaaa string, it will throw an error, but logs a quick report before.
The report generates 3 random numbers in a row, and adds it to the log:
SHARED_RANDOM.Next(20);
SHARED_RANDOM.Next(20);
SHARED_RANDOM.Next(20);
The 3 numbers produced are 0, nice uh ?
This tells me that the issue is not the GetRandomAlphaNumericString, but the Random object itself.
There is some sort of corruption that causes the object to return those results, so basically it could be anything ?!
Related
Hold on: It's not as easy as it sounds in the title.
I've been working on a very crude AI, and the seemingly hard bits have been easy but this one little function is being really hard.
What I want this to do is get some of the chars that occur before a chars in the string. For example,
get_piece_behind("Hello World", 5, 3) #Return the 3 chars that come before ' ' (the fifth char)
'llo'
get_piece_behind("Hello World", 4, 3) #Return the 3 chars that come before 'o' in "hello" (the fourth char)
'ell'
get_piece_behind("Hello World", 5, 2) #Return the 2 chars that come before the fifth char
'lo'
The code accepts a string, an int marking a place in the string, and an int telling the function how far back it should look.
I get the idea this should be a super-simple one-liner... but my coffee infused brain has been staring at it for the past hour, rewriting it over and over, and nothing seems to work (my current function returns small bits of string, but from the wrong place)
def get_piece_behind(string, place, length_of_piece): #My current function
string = string[(place - length_of_piece):]
string = string[:place]
return string
Does anyone know how to fix this? I get the idea that it's a tiny, stupid error that I will have completely overlooked.
Thanks!
Python strings are sequences, and as such you can use the slice-index syntax to retrieve sub-sequeces of it:
a = "hello world"
a[1:3] # retrieves the chars from the second posistion (index 1) up to the 4th.
# the same, but as you want, putting expressins to calculate the indexes:
a[5-3:5]
a[4-3:4]
I suggest you to read the following document in whole before proceeding with your task - might save you a lot of time:
https://docs.python.org/3/tutorial/introduction.html
You are overlooking in your string splicing.
Try this:
def get_piece_behind(string, place, length_of_piece):
string = string[(place-length_of_piece) : place]
return string
Just do it in one line :) since your string change after first reassignment, also character positions will change:
def get_piece_behind(_string, place, length_of_piece): #My current function
_string = _string[(place - length_of_piece):place]
return _string
The index of characters changes as you cut first with place - length_of_piece, which gives 2, so you were cutting from third char, "llo World" then 5 characters before, resulting in "llo W".
This should work for you:
def get_piece_behind(string, place, length_of_piece):
return string[place-length_of_piece:place]
Output:
llo
ell
lo
I have the following code in node and I am trying to convert to ColdFusion:
// a correct implementation of PKCS7. The rijndael js has a PKCS7 padding already implemented
// however, it incorrectly pads expecting the phrase to be multiples of 32 bytes when it should pad based on multiples
// 16 bytes. Also, every javascript implementation of PKCS7 assumes utf-8 char encoding. C# however is unicode or utf-16.
// This means that chars need to be treated in our code as 2 byte chars and not 1 byte chars.
function padBytes(string){
const strArray = [...new Buffer(string, 'ucs2')];
const need = 16 - ((strArray.length) % 16);
for(let i = 0; i < need; i++) {
strArray.push(need);
}
return Buffer.from(strArray);
}
I'm trying to understand exactly what this function is doing to convert it. As I think I understand it, it's converting the string to UTF-16 (UCS2) and then adding padding to each character. However, I don't understand why the need variable is the value it is, nor how exactly to achieve that in CF.
I also don't understand why it's only pushing the same value into the array over and over again. For starters, in my example script the string is 2018-06-14T15:44:10Z testaccount. The string array length is 64. I'm not sure how to achieve even that in CF.
I've tried character encoding, converting to binary and stuff to UTF-16 and just don't understand well enough the js function to replicate it in ColdFusion. I feel I'm missing something with the encoding.
EDIT:
The selected answer solves this problem, but because I was eventually trying to use the input data for encryption, the easier method was to not use this function at all but do the following:
<cfset stringToEncrypt = charsetDecode(input,"utf-16le") />
<cfset variables.result = EncryptBinary(stringToEncrypt, theKey, theAlgorithm, theIV) />
Update:
We followed up in chat and turns out the value is ultimately used with encrypt(). Since encrypt() already handles padding (automatically), no need for the custom padBytes() function. However, it did require switching to the less commonly used encryptBinary() function to maintain the UTF-16 encoding. The regular encrypt() function only handles UTF-8, which produces totally different results.
Trycf.com Example:
// Result with sample key/iv: P22lWwtD8pDrNdQGRb2T/w==
result = encrypt("abc", theKey, theAlgorithm, theEncoding, theIV);
// Result Result with sample key/iv: LJCROj8trkXVq1Q8SQNrbA==
input = charsetDecode("abc", "utf-16le");
result= binaryEncode(encryptBinary(input, theKey, theAlgorithm, theIV), "base64);
it's converting the string to utf-16
(ucs2) and then adding padding to each character.
... I feel I'm missing something with the encoding.
Yes, the first part seems to be decoding the string as UTF-16 (or UCS2 which are slightly different). As to what you're missing, you're not the only one. I couldn't get it to work either until I found this comment which explained "UTF-16" prepends a BOM. To omit the BOM, use either "UTF-16BE" or "UTF-16LE" depending on the endianess needed.
why it's only pushing the same value into the array over and over again.
Because that's the definition of PCKS7 padding. Instead of padding with something like nulls or zeroes, it calculates how many bytes padding are needed. Then uses that number as the padding value. For example, say a string needs an extra three bytes padding. PCKS7 appends the value 3 - three times: "string" + "3" + "3" + "3".
The rest of the code is similar in CF. Unfortunately, the results of charsetDecode() aren't mutable. You must build a separate array to hold the padding, then combine the two.
Note, this example combines the arrays using CF2016 specific syntax, but it could also be done with a simple loop instead
Function:
function padBytes(string text){
var combined = [];
var padding = [];
// decode as utf-16
var decoded = charsetDecode(arguments.text,"utf-16le");
// how many padding bytes are needed?
var need = 16 - (arrayLen(decoded) % 16);
// fill array with any padding bytes
for(var i = 0; i < need; i++) {
padding.append(need);
}
// concatenate the two arrays
// CF2016+ specific syntax. For earlier versions, use a loop
combined = combined.append(decoded, true);
combined = combined.append(padding, true);
return combined;
}
Usage:
result = padBytes("2018-06-14T15:44:10Z testaccount");
writeDump(binaryEncode( javacast("byte[]", result), "base64"));
for(int i=0;i<5;i++)
{
char ans = s.next().charAt(i);
}
I am getting a StringIndexOutOfBoundsException. Why it is happening?
Because s.next() is returning a String with less than 5 characters. Try printing out s.next() to see the value if you expected it to be longer.
You are getting the exception cause you are trying to assign a char in your "ans" variable which is not available. The reason behind this is, the string you're getting by calling the 's.next()' method is not returning a string with at least 5 characters. Let's say the string is "Me" and you're trying to loop through it 5 times where there is only two characters. So when you're trying to look for the 3rd indexed character there is none and so you're getting the "StringIndexOutOfBoundsException"......
You can also re-use the Scanner object, there's no need to create a new one for each user input.
And: "charCount = charCount++;" --> "charCount++;"
Today I've finally decided to make an account, in hope for some aid in an issue I've spent the last few hours hunting. (I've spent the past couple hours hunting down a response, from Google to here to Unity Answers. Here's everything that I've found so far, which doesn't work.)
What I'm looking for, is to change a string of purely words/letters into an integer. Therefore "Hello World", would be translated into a string of numbers accordingly. This may be surprising, but this is a lot harder than it sounds. I've found a way to do essentially everything but, thus far.
Presumably the best way would be to get the ASCII value of each letter in the string, and put them all together into a single integer. (No sequences or need to separate them, but one single number.) I have no idea where to get started or how to do that, however. Really anything that you think would work, preferably as short-hand and un-bothersome as possible.
To be as clear as possible, I need to take the letter-only variable "example" and transmorph it to be a integer/only a sequence of numbers.
If you're just trying to convert an arbitrary string into a random seed, then why not try randomSeed.GetHashCode()? That will return an int value suitable for setting the seed, which would produce the same number each time the same string is entered.
You can iterate over all characters, get their charCode and chain them together. The first method splits the string into single chars and uses Array.reduce:
var str = 'qwertzuiop';
var num = parseInt(str.split('').reduce(function(a, b) {return a + b.charCodeAt(0);}, '');
The second calls Array.forEach on the string, because it has numerical indices and a length property.
var num = ''; [].forEach.call(str, function(c) {num += c.charCodeAt(0);});
num = parseInt(num);
In stoneaged browsers you have to use for-loops instead.
I am creating a custom field where I want to replace some unicode caracters by pictures. Its like doing emoticons for blackberry device. Well I have a problem looping the caracters in the edit field and replacing the unicode caracters by images. When the text becomes too long, the loop takes too much time.
My code is as follows:
String aabb = "";
char[] chara = this.getText().toCharArray();
for (int i = loc; i < chara.length; i ++) {
Character cc = new Character(chara[i]);
aabb += cc.toString();
if (unicodeCaracter) {
//Get the location
//draw the image in the appropriate X and Y
}
}
Well this works fine, and the images are getting in the right place. But the problem is when the text becomes large, the looping is taking too much time, and the input of the text on the device becomes non friendly.
How to find the unicode caracters in a text without having to loop each time for them? Is their another way than this that I missed?
I need help with this issue. Thanks in advance
Well you're creating a new Character and a new String in each iteration of the loop, and converting the string to a character array to start with. You're also using string concatenation in a loop rather than using a StringBuffer. All of these will be hurting performance.
It's not obvious what you mean by "Unicode characters" here - all characters in Java are Unicode characters. I suspect you really want something like:
String text = this.getText();
StringBuffer buffer = new StringBuffer(text.length());
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
buffer.append(c);
if (c > 127) { // Or whatever
// Take some action
}
}
I'm assuming the "take some action" will be changing the buffer in some respect, otherwise the buffer is pointless of course... but fundamentally that's likely to be the sort of change you want.
The string concatenation in a loop is a particularly bad idea - see my article on it for more details.
What takes time is the string concatenation.
Strings are immutable in Java. Each time you do
aabb += cc.toString();
you create a new String object containing all the chars of the previous one, which must be garbage collected, plus the new ones. Use a StringBuilder to build your string:
StringBuilder builder = new StringBuilder(this.getText().length() + 100); // size estimation
char[] chara = this.getText().toCharArray();
for (int i = loc; i < chara.length; i++) {
builder.append(chara[i]);
if (unicodeCaracter) {
//Get the location
//draw the image in the appropriate X and Y
}
}
String aabb = builder.toString();
Well, besides speeding up your loop, you could also try and minimize the work load.
If the user is appending text you could store the last position you scanned previously time and start from there..
On inserts/deletes you'd need to get the caret position and scan the deleted/inserted part and maybe surrounding characters (if you have character groups instead of single characters that get replaced).
However, fixing loop performance is likely to give you a better improvement in your case, as I doubt you'll have that long strings to make that algorithmic change worthwhile.
The most important performance enhancements have already been stated but looping backwards will also help in BlackBerry apps.
Programming Tips: General Coding Tips