Hey guy's I tried to find a way to hide a string, but the code that I found just work with my application... Is there a way to hide the characters in a string with either *
or -
and if there is can someone please explain
Is this for making a password? Consider the following:
class Password {
final String password; // the string to mask
Password(String password) { this.password = password; } // needs null protection
// allow this to be equal to any string
// reconsider this approach if adding it to a map or something?
public boolean equals(Object o) {
return password.equals(o);
}
// we don't need anything special that the string doesnt
public int hashCode() { return password.hashCode(); }
// send stars if anyone asks to see the string - consider sending just
// "******" instead of the length, that way you don't reveal the password's length
// which might be protected information
public String toString() {
StringBuilder sb = new StringBuilder();
for(int i = 0; < password.length(); i++)
sb.append("*");
return sb.toString();
}
}
Or for the hangman approach
class Hangman {
final String word;
final BitSet revealed;
public Hangman(String word) {
this.word = word;
this.revealed = new BitSet(word.length());
reveal(' ');
reveal('-');
}
public void reveal(char c) {
for(int i = 0; i < word.length; i++) {
if(word.charAt(i) == c) revealed.set(i);
}
}
public boolean solve(String guess) {
return word.equals(guess);
}
public String toString() {
StringBuilder sb = new StringBuilder(word.length());
for(int i = 0; i < word.length; i++) {
char c = revealed.isSet(i) ? word.charAt(i) : "*";
}
return sb.toString();
}
}
Just create a string with the same number of characters as your original, with instead your "obfuscating" character.
String x = "ABCD";
String output = "";
for (int i = 0; i < x.length(); i++) {
output += "*";
}
Alternatively you could use x.replaceAll("\\S", "*")
, which would preserve whitespace as well.
[\s\S]
–
Usury replaceAll
with the pattern I mentioned "would preserve whitespace". That is, would only replace non-whitespace characters with an asterisk. So "hello world" would become "***** *****". The regex you provided would not preserve the whitespace. –
Frolic replaceAll
was suggested as as alternative which would preserve whitespace if so desired. The previous for-loop would replace all characters. –
Frolic \S
pattern over the [\s\S]
. How is preserving whitespace in a password legit, when and where is that ever done? You answer is non sense. –
Usury \s\S
is no more correct: to hide all characters including white space, the correct pattern to use would be .
–
Frolic There are several ways to achieve this, it would depend on your application.
If you want to mask all characters with another character in one fell swoop you can use the String#replaceAll(String regex, String replacement)
method: http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#replaceAll(java.lang.String,%20java.lang.String).
This involves using Regular Expressions, for regex
you would use [\s\S]
which will match any whitespace or non whitespace character. For replacement
you use a regular string, not a RegEx. In this case, if you wanted an asterisk, use "*", for hyphen "-", very simple.
All the other methods here work well except the @Roddy of the Frozen Pea
and @djc391
ones, so that's why I answered it correctly.
Good luck
You could easily implement something like this:
public class MaskedString
{
private String data;
public MaskedString(String data){this.data = data;}
public void append(char c){data += c;}
public void setData(String data){this.data = data;}
public String getMasked()
{
StringBuilder sb = new StringBuilder();
for(int i=0; i<data.length(); i++)
sb.append('*');
return sb.toString();
}
public String getString()
{
return data;
}
}
You get the idea :)
My implementation:
public static String maskString(String s, int x) {
int n = s.length()/x;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
if (n >= 1 && (i < n || i >= (s.length() - n))) {
sb.append(s.charAt(i));
}
else {
sb.append("*");
}
}
return sb.toString();
}
This is a generic way of masking and it can be used to mask an entire String or a particular portion of the String.
Parameters required
data
-> The String that needs to be masked.from
-> Index from where the masking should start.to
-> Index till where the masking should continue.maskWith
-> Character with which you want to mask.
The first thing is to get the masked data, using a for loop starting with from
and ending with to
, inside the loop append the maskWith
to a StringBuilder
. Now, you need to get the portion from the data
that needs to be masked, you can use the substring
method with from
and to
as arguments respectively. Finally, use the replace
method by supplying the above substring as the first argument and the masked String as the second argument.
Code
public static String maskData(String data, int from, int to, char maskWith) {
StringBuilder maskedPart = new StringBuilder();
for(int i=from; i<to; i++)
maskedPart.append(maskWith);
return data.replace(data.substring(from, to), maskedPart.toString());
}
Sample value
public static void main(String[] args) {
System.out.println(maskData("9999123456789999", 4, 12, 'X'));
}
Output
9999XXXXXXXX9999
If you are looking for simple implementation, you can use below function:
Kotlin:
fun String.mask(
maskString: String = "x",
maskAfterLetters: Int = 3,
isFixSize: Boolean = true,
maxSize: Int = 10,
selector: String = "."
): String {
if(maskAfterLetters < 0) throw IllegalArgumentException("Invalid masking configuration - maskAfterLetters should be greater than 0")
if(isFixSize && maxSize <= maskAfterLetters) throw IllegalArgumentException("Invalid masking configuration - maxSize must be greater than maskAfterLetters")
val text = if(isFixSize && length >= maxSize) substring(0, maxSize) else this
val unmaskLength = if(maskAfterLetters <= length) maskAfterLetters else length
return text.substring(0, unmaskLength) + text.substring(unmaskLength, text.length).replace(selector.toRegex(), maskString)
}
Java:
/*
For Java,
Additional input parameter named inputStringToBeMasked which is the actual string which has to be masked.
*/
public static String mask(
String inputStringToBeMasked,
String maskString,
Integer maskAfterLetters,
Boolean isFixSize,
Integer maxSize,
String selector
) {
//check input and set default if input parameters are not passed
if(null == maskString || maskString.isEmpty()) maskString = "x";
if(null == maskAfterLetters) maskAfterLetters = 3;
if(null == isFixSize) isFixSize = true;
if(null == maxSize) maxSize = 10;
if(null == selector || selector.isEmpty()) selector = ".";
if(maskAfterLetters < 0) throw new IllegalArgumentException("Invalid masking configuration - maskAfterLetters should be greater than 0");
if(isFixSize && maxSize <= maskAfterLetters) throw new IllegalArgumentException("Invalid masking configuration - maxSize must be greater than maskAfterLetters");
String text = (isFixSize && inputStringToBeMasked.length() >= maxSize) ? inputStringToBeMasked.substring(0, maxSize) : inputStringToBeMasked;
Integer unmaskLength = (maskAfterLetters <= inputStringToBeMasked.length()) ? maskAfterLetters : inputStringToBeMasked.length();
return text.substring(0, unmaskLength) + text.substring(unmaskLength, text.length()).replaceAll(selector, maskString);
}
Note: This method in Kotlin, you can covert it in Java easily.
where,
maskString
: is an string which is to be replaced with characters being maskedmaskAfterLetters
: initial given letters are kept original and then masking startedisFixSize
: is given masked result with fixed size of based on input string sizemaxSize
: ifisFixSize
is true then provided the size of masked stringselector
: (no change needed) used for selection of characters to be masked
If you are looking for automated masking while serialization and deserialization, you can use json-masker which is an annotation based making solution.
© 2022 - 2024 — McMap. All rights reserved.