Generation of Referral or coupon code - java

How can I generate readable referral code for users. I am using Java 7 programming language and MySQL db. I am searching for this from week but not getting appropriate solution.
Any help will be appreciated. Thanks in advance.

For maintaining Uniqueness keep the codeLength as large as you can means atleast 6 or 8. Also you can include capital Alphabets also in chars array so that uniqueness also can get increased as more combinations can be served. Including capital letters also, you can serve upto 64^8 unique random codes ideally.
public String createRandomCode(int codeLength){
char[] chars = "abcdefghijklmnopqrstuvwxyz1234567890".toCharArray();
StringBuilder sb = new StringBuilder();
Random random = new SecureRandom();
for (int i = 0; i < codeLength; i++) {
char c = chars[random.nextInt(chars.length)];
sb.append(c);
}
String output = sb.toString();
System.out.println(output);
return output ;
}

Related

Extremely compact UUID (using all alphanumeric characters)

I need an extremely compact UUID, the shorter the better.
To that end, I wrote:
public String getBase36UIID() {
// More compact version of UUID
String strUUID = UUID.randomUUID().toString().replace("-", "");
return new BigInteger(strUUID, 16).toString(36);
}
By executing this code, I get, for example:
5luppaye6086d5wp4fqyz57xb
That's good, but it's not the best. Base 36 uses all numeric digits and lowercase letters, but does not use uppercase letters.
If it were possible to use uppercase letters as separate digits from lowercase letters, it would be possible to theorize a numerical base 62, composed of these digits:
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
I could theorize numerical bases also using accented characters such as "è" or "é", or special characters such as "$" or "!", further increasing the number of digits available.
The use of these accented or special characters, however, may cause me problems, so for the moment I prefer not to consider them.
After all these premises, how can I convert the BigInteger representing my UUID into the base 62 above theorized, in order to make it even more compact? Thanks
I have already verified that a code like the following is not usable, because every base over 36 is treated as base 10:
return new BigInteger(strUUID, 16).toString(62);
After all, in mathematics there is no base 62 as I imagined it, but I suppose that in Java it can be created.
The general algorithm for converting a number to any base is based on division with remainder.
You start by dividing the number by the base. The remainder gives you the last digit of the number - you map it to a symbol. If the quotient is nonzero, you divide it by the base. The remainder gives you the second to last digit. And you repeat the process with the quotient.
In Java, with BigInteger:
String toBase62(BigInteger number) {
String symbols = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
BigInteger base = BigInteger.valueOf(symbols.length());
StringBuilder result = new StringBuilder();
do {
BigInteger[] quotientAndRemainder = number.divideAndRemainder(base);
number = quotientAndRemainder[0];
result.append(symbols.charAt(quotientAndRemainder[1].intValue()));
} while (number.compareTo(BigInteger.ZERO) > 0);
return result.reverse().toString();
}
Do you need the identifier to be a UUID though? Couldn't it be just any random sequence of letters and numbers? If that's acceptable, you don't have to deal with number base conversions.
String randomString(int length) {
String symbols = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
Random rnd = new Random();
StringBuilder str = new StringBuilder();
for (int i = 0; i < length; i++) {
str.append(symbols.charAt(rnd.nextInt(symbols.length())));
}
return str.toString();
}
This should not be difficult. Converting a number to a string is a basic programming task. The fact that you're using base 62 makes no difference.
Decide how many characters you're willing to use, and then convert your large number to that base. Map each "digit" onto one of the characters.
Pseudocode:
b = the base (say, 62)
valid_chars = an array of 'b' characters
u = the uuid
while u != 0:
digit = u % b;
char = valid_chars[digit];
u = u / b;
This produces the digits right-to-left but you should get the idea.
Main idea is the same as previous posts, but the implementation have some differences.
Also note that if wanted different occurrence probability for each chars this can be adjusted also.(mainly add a character more time on a data structure and change his probability)
Here is fair-probability for each chars (equals, 1/62)
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class RCode {
String symbols = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static void main(String[] args)
{
RCode r = new RCode();
System.out.println("symbols="+r.symbols.length());
System.out.println("code_10(+1)="+r.generate(10));
System.out.println("code_70(+2)="+r.generate(70));
//System.out.println("code_124(+3)="+r.generate(124));
}
public String generate(int length)
{
int num = length/symbols.length()+1;
List<Character> list = new ArrayList<Character>();
for(int i=0; i<symbols.length(); i++)
{
//if needed to change probability of char occurrence then adapt here
for(int j=0;j<=num;j++)
{
list.add(symbols.charAt(i));
}
}
//basically is the same as random
Collections.shuffle(list);
StringBuffer sb = new StringBuffer();
for(int i=0; i<length; i++)
{
sb.append(list.get(i));
}
return sb.toString();
}
}
Output:
symbols=62
//each char is added once(+1)
code_10(+1)=hFW9ZFEAeU
code_70(+2)=hrHQCEdQ3F28apcJPnfjAaOu55Xso12xabkJ7MrU97U0HYkYhWwGEqVAiLOp3X3QSuq6qp
Note: Algorithm have a defect, just try to figured out why the sequence will be never generate on 10 (aaaaaaaaaa). Easy to fix ... but i was focused on the idea.
Now, as it is, basically is generating up to num each character. (random and maybe for someone will be useful the output)

How to Random generate a value like this 23-4564567

I am looking for how I can random generate a value like this 23-3455673. My issue is I'm not sure how to get the - in the middle of my random numeric code.
I am using a Maven java project and using the RandomStringUtils.randomnumeric(10)
So looking for a way to random generate the value as 23-5672345 basically two digits then a - then 7 digits all in a single string.
I'm not super skilled here so i really am not looking for highly technical answers just the simplest method to make this work is what I'm looking for.
Thanks in advance for any advise on how to accomplish this.
I would generate a String with length 9, then insert - at index 2:
String nineDigit = RandomStringUtils.randomNumeric(9);
StringBuilder stringBuilder = new StringBuilder(nineDigit);
String result = stringBuilder.insert(2, "-").toString();
System.out.println(result);
I am not sure what you mean by "in maven" but as you are using RandomStringUtils.randomnumeric(10) you can use
StringBuilder sb =new StringBuilder(RandomStringUtils.randomNumeric(2)).append("-").append(RandomStringUtils.randomNumeric(7))
String result=sb.toString()
System.out.println(result);
Without third party libraries :
1) The easy solution : generate 2 digits, then append - then generate 7 digits :
Random random = new Random();
StringBuilder sb = new StringBuilder();
//Append a number between [0; 10[
sb.append(random.nextInt(10));
sb.append(random.nextInt(10));
sb.append('-');
for (int i = 0; i < 7; i++) {
sb.append(random.nextInt(10));
}
System.out.println(sb);
Output :
77-5711939
2) The concise solution : generate a 9 digits string.
random.nextInt(1_000_000_000)
but if the generated value is less than 100_000_000, you are not guaranteed to have 9 digits. Hence, you will pad the value with String.format() :
// %09d imposes 9 digits. 0 are added if necessary.
// String.format("%09d", 42) returns 000000042
String result = String.format("%09d", random.nextInt(1_000_000_000));
Then you can insert a - at the 2nd position.

Random seed generator

EDIT: Sorry for wrong posting, I'll check the forum locations better next time. I selected an answer as accepted, I think this considers the question closed. Thanks for the helpful replies and tips!
Original:
I need to upgrade to the new Iota wallet today. It doesn't have a random seed generator, so I built my own and ran it from NetBeans. Can you give me your opinion? It has to be 81 characters long, and contain A through Z and the number 9. Nothing else. Here's the entire code.
Does this leave anything insecure? Could the code have been cleaner from a standpoint of convention?
class SeedGenerator {
/*
This is a program to randomize a seed for Iota wallet
*/
public static void main(String[] args) {
System.out.println("*****");
int seedLength = 81;
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ9"; //Only characters allowed in Iota seed are A-Z and number 9
char[] charArray = alphabet.toCharArray(); //Turn string into array of characters to be referenced by index
String[] seed = new String[seedLength];
System.out.print("Random wallet seed is: ");
for (int i = 0; i < seedLength; i++) {
Random newRandomNumber = new Random();
int seedIndex = newRandomNumber.nextInt(alphabet.length()); //This is an array of index numbers to pull from charArray
// System.out.print(seedIndex + " "); //Used for testing the random character index range
seed[i] += charArray[seedIndex];
System.out.print(charArray[seedIndex] + "");
}
System.out.println();
System.out.println("*****");
}
}
When asking for code to be reviewed, you should post it here. But regardless of that, there are much more efficient ways to generate a random character.
One such way would be to generate a random character between 65 and 90, the decimal values for A-Z on the ASCII table. And then, just cast the value as a char to get the actual letter corresponding to the number. However, you say that you want the number 9 to also be included, so you can extend this to 91, and if you get 91, which on the ASCII table is [, add the number 9 to your string instead of that.
This code accomplishes that quite easily:
String mySeed = "";
for(int i=0; i<81; i++)
{
int randomNum = (int)(Math.random()*27) + 65;
if(randomNum==91)
mySeed+="9";
else
mySeed+=(char)randomNum;
}
System.out.println(mySeed);
And, as mentioned by #O.O. you can look at generating a secure random number here.
I recommend to use the offical IOTA Java library named Jota.
Class SeedRandomGenerator has a generateNewSeed implementation:
public static String generateNewSeed() {
char[] chars = Constants.TRYTE_ALPHABET.toCharArray();
StringBuilder builder = new StringBuilder();
SecureRandom random = new SecureRandom();
for (int i = 0; i < Constants.SEED_LENGTH_MAX; i++) {
char c = chars[random.nextInt(chars.length)];
builder.append(c);
}
return builder.toString();
}
Find the constants for TRYTES_ALPHABET and SEED_LENGTH_MAX in Constants class.

From string to ASCII to binary back to ASCII to string in Java

I have sort of a funky question (that I hope hasn't been asked and answered yet). To start, I'll tell you the order of what I'm trying to do and how I'm doing it and then tell you where I'm having a problem:
Convert a string of characters into ASCII numbers
Convert those ASCII numbers into binary and store them in a string
Convert those binary numbers back into ASCII numbers
Convert the ASCII numbers back into normal characters
Here are the methods I've written so far:
public static String strToBinary(String inputString){
int[] ASCIIHolder = new int[inputString.length()];
//Storing ASCII representation of characters in array of ints
for(int index = 0; index < inputString.length(); index++){
ASCIIHolder[index] = (int)inputString.charAt(index);
}
StringBuffer binaryStringBuffer = new StringBuffer();
/* Now appending values of ASCIIHolder to binaryStringBuffer using
* Integer.toBinaryString in a for loop. Should not get an out of bounds
* exception because more than 1 element will be added to StringBuffer
* each iteration.
*/
for(int index =0;index <inputString.length();index ++){
binaryStringBuffer.append(Integer.toBinaryString
(ASCIIHolder[index]));
}
String binaryToBeReturned = binaryStringBuffer.toString();
binaryToBeReturned.replace(" ", "");
return binaryToBeReturned;
}
public static String binaryToString(String binaryString){
int charCode = Integer.parseInt(binaryString, 2);
String returnString = new Character((char)charCode).toString();
return returnString;
}
I'm getting a NumberFormatException when I run the code and I think it's because the program is trying to convert the binary digits as one entire binary number rather than as separate letters. Based on what you see here, is there a better way to do this overall and/or how can I tell the computer to recognize the ASCII characters when it's iterating through the binary code? Hope that's clear and if not I'll be checking for comments.
So I used OP's code with some modifications and it works really well for me.
I'll post it here for future people. I don't think OP needs it anymore because he probably figured it out in the past 2 years.
public class Convert
{
public String strToBinary(String inputString){
int[] ASCIIHolder = new int[inputString.length()];
//Storing ASCII representation of characters in array of ints
for(int index = 0; index < inputString.length(); index++){
ASCIIHolder[index] = (int)inputString.charAt(index);
}
StringBuffer binaryStringBuffer = new StringBuffer();
/* Now appending values of ASCIIHolder to binaryStringBuffer using
* Integer.toBinaryString in a for loop. Should not get an out of bounds
* exception because more than 1 element will be added to StringBuffer
* each iteration.
*/
for(int index =0;index <inputString.length();index ++){
binaryStringBuffer.append(Integer.toBinaryString
(ASCIIHolder[index]));
}
String binaryToBeReturned = binaryStringBuffer.toString();
binaryToBeReturned.replace(" ", "");
return binaryToBeReturned;
}
public String binaryToString(String binaryString){
String returnString = "";
int charCode;
for(int i = 0; i < binaryString.length(); i+=7)
{
charCode = Integer.parseInt(binaryString.substring(i, i+7), 2);
String returnChar = new Character((char)charCode).toString();
returnString += returnChar;
}
return returnString;
}
}
I'd like to thank OP for writing most of it out for me. Fixing errors is much easier than writing new code.
You've got at least two problems here:
You're just concatenating the binary strings, with no separators. So if you had "1100" and then "0011" you'd get "11000011" which is the same result as if you had "1" followed by "1000011".
You're calling String.replace and ignoring the return result. This sort of doesn't matter as you're replacing spaces, and there won't be any spaces anyway... but there should be!
Of course you don't have to use separators - but if you don't, you need to make sure that you include all 16 bits of each UTF-16 code point. (Or validate that your string only uses a limited range of characters and go down to an appropriate number of bits, e.g. 8 bits for ISO-8859-1 or 7 bits for ASCII.)
(I have to wonder what the point of all of this is. Homework? I can't see this being useful in real life.)

Convert foreign characthers (Greek) to English ones.

I am installing alarms, but they have an interface that I have to give name to various zones. The problem is that they can only accept greek characters that does not exist in english language else they have to be the English equivelant.
For example if I write "ΠΑΡΑΘΥΡΟ", the characthers 1,2,3,5,6,7 must enter in english because are the same with the greek ones in appearence. But chars 0 and 4 only must be in Greek.
I care only for capitals.
Any idea on how to do it with 2 simple jtextfields ?
Thank you!
Use a HashMap to translate characters. Since the problem domain is small and will probably never change, it's justifiable to hard-code the content of the map, like so:
private static final Map<Character, Character> GREEK_TO_ROMAN = new HashMap<>();
static {
GREEK_TO_ROMAN.put('\u0391', '\u0041'); // uppercase alpha
GREEK_TO_ROMAN.put('\u03A1', '\u0050'); // uppercase rho
// ...
}
Then get the input string's character array, translate characters as needed, and create a new String from the changed array:
String s = "ΠΑΡΑΘΥΡΟ";
char[] chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
Character repl = GREEK_TO_ROMAN.get(chars[i]);
if (repl != null)
chars[i] = repl;
}
s = new String(chars);
How JTextField would come into play I don't quite see, but maybe if you want you can subclass it, overwrite the getText() method and make sure that any String it yields is already converted.

Categories