简体   繁体   English

如何随机化字符串中字母的大小写

[英]How to randomize the case of letters in a string

I want to write some automated tests for web app authentication. 我想为Web应用程序身份验证编写一些自动化测试。 The login password is case-sensitive and always contains at least one alphabetic character. 登录密码区分大小写,并且始终至少包含一个字母字符。

I want to write a test where I randomly change the case of one or more alphabetic characters. 我想编写一个测试,在其中我随机更改一个或多个字母字符的大小写。

Let's say the password string is "123te123st!" 假设密码字符串为"123te123st!" .

Now I want to change this string to one which contains at least one uppercase letter. 现在,我想将此字符串更改为包含至少一个大写字母的字符串。 I'm trying to make sure that the login is still case-insensitive and any variation in case will fail to match the password. 我试图确保登录名仍然不区分大小写,以防万一与密码不符的任何变化。

Does anybody know a elegant way to do it? 有人知道这样做的优雅方式吗? I searched already (including Apache Commons) but couldn't find a helper method. 我已经搜索了(包括Apache Commons),但是找不到帮助方法。

You can look at the randomAlphaNumeric from the RandomStringUtils , although it would seem that you are not guaranteed for it to have an upper case. 你可以看一下randomAlphaNumericRandomStringUtils ,尽管这似乎是你不能保证它有一个大写字母。 To go around this, you could get the first lowercase letter and use the .toUpper() method to get it to upper case. 要解决此问题,您可以获取第一个小写字母并使用.toUpper()方法将其转换为大写字母。

Alternatively, you could generate random numbers between 0 and 9 and 65 and 90 and 97 and 122. The first set should get you random numbers, you could then cast the second number to a character to get your upper case letter(s) and do the same on the last number to get your lower case ones. 或者,您可以生成0到9到65到90到97到122之间的随机数。第一个集合应该为您提供随机数,然后可以将第二个数字转换为字符以获取大写字母并执行最后一个数字相同,以获得小写字母。

That being said, when testing one usually goes for data which is predetermined rather than generating data on the fly, since that would make it easier to debug. 话虽如此,在测试时通常会选择预先确定的数据,而不是即时生成数据,因为这样做会使调试更加容易。 Having a simple pool of passwords might also be easier to implement and would also allow you to better test edge cases. 具有简单的密码池也可能更易于实现,并且还可以使您更好地测试边缘情况。

class Case
{
  public static void main(String ar[])
  {
    String s = "upperCase",split[];
    split = s.split("");
    int len = s.length(),i=0;
    while(i!=len)
    {
        if(split[i].toUpperCase() == split[i])
        {   
            System.out.println("Password Contains One UpperCase Latter");
            break;
        }
        i++;
    }
  }
}

By using this code u can easily check whether string contain uppercase or not. 通过使用此代码,您可以轻松地检查字符串是否包含大写字母。 if output prints "Password Contains One Uppercase Latter" this message then string contain at least on uppercase. 如果输出显示“密码包含一个大写字母”,则该消息然后字符串至少包含大写字母。

In this case output would like: 在这种情况下,输出将是:

在此处输入图片说明

To generate all capitalized variants of a string, it makes sense to scan the string and store the position of each letter in a list. 要生成字符串的所有大写变体,请扫描字符串并将每个字母的位置存储在列表中,这很有意义。 This will let you iterate over the letters while skipping the non-letter characters. 这将使您在跳过非字母字符的同时迭代字母。

For example, for the string "_a_b_c_" , you want to store the positions [1, 3, 5] . 例如,对于字符串"_a_b_c_" ,您要存储位置[1, 3, 5]

Next, make a boolean array of the same length as the list of letter positions. 接下来,创建一个长度与字母位置列表相同的布尔数组。 This will represent the positions of letters that have had their case inverted. 这将代表大小写颠倒的字母的位置。

To generate the next capitalized variant, pretend that the boolean array represents a binary number in reverse. 要生成下一个大写的变体,请假装布尔数组代表相反的二进制数。 Add 1 to that boolean number, which means scanning the array from the beginning, flipping each true to false until you reach a false , which you flip to true . 向该布尔数加1,这意味着从头开始扫描数组,将每个true翻转为false直到遇到false ,然后翻转为true As you flip each bit, invert the case of the corresponding character in the string. 翻转每一位时,请反转字符串中相应字符的大小写。

Thus, we get the following 2 3 - 1 = 7 variants of "_a_b_c_" : 因此,我们得到以下2 3 - 1 = 7种变体"_a_b_c_"

binary number  reversed   capitalized variant
        001       100      _A_b_c_
        010       010      _a_B_c_
        011       110      _A_B_c_
        100       001      _a_b_C_
        101       101      _A_b_C_
        110       011      _a_B_C_
        111       111      _A_B_C_

Here is a complete Java implementation. 这是一个完整的Java实现。

import java.util.*;
import java.io.*;

public class VaryCaps {

  int wordLength,
      numLetters;
  Integer letterPositions[];
  boolean inverted[];
  StringBuffer buffer;

  public VaryCaps(String word) {
    wordLength = word.length();
    List<Integer> positionList = new ArrayList<Integer>();
    for (int i = 0; i < wordLength; ++i) {
      if (Character.isLetter(word.charAt(i))) {
        positionList.add(i);
      }
    }
    numLetters = positionList.size();
    letterPositions = positionList.toArray(new Integer[numLetters]);
    inverted = new boolean[numLetters];
    buffer = new StringBuffer(word);
  }

  private void invert(int index) {
    int pos = letterPositions[index];
    char ch = buffer.charAt(pos);
    if (Character.isUpperCase(ch)) {
      ch = Character.toLowerCase(ch);
    } else {
      ch = Character.toUpperCase(ch);
    }
    buffer.setCharAt(pos, ch);
    inverted[index] = !inverted[index];
  }

  public String next() {
    int index = 0;
    while (index < numLetters && inverted[index]) {
      invert(index++);
    }
    if (index == numLetters) {
      return null;
    }
    invert(index);
    return buffer.toString();
  }

  public static void main(String[] args) {
    VaryCaps rc = new VaryCaps("_a_b_c_");
    String s;
    while ((s = rc.next()) != null) {
      System.out.println(s);
    }
  }
}

You can try like this: 您可以这样尝试:

public class Test{

    public static void main(String[] args){
        String s = "1a23test12hjsd2"; // Take it as a password
        char[] c= s.toCharArray(); //Convert string in chararray
        boolean flag= false;
        StringBuilder s1= new StringBuilder();
        for(int d:c){
            if(d>=97 && d<=122 && !flag){ //Converting lowercase to upper case
                d=d-32;
                flag=true;
            }
            s1.append((char)d);
        }
        System.out.println(s1);
    }
}

You can use this class to generate random passwords with a constraint on uppercase letters. 您可以使用此类生成具有大写字母约束的随机密码。

import java.util.Random;

public class RandomPasswordGenerator {
    private static final String ALPHA_CAPS  = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String ALPHA   = "abcdefghijklmnopqrstuvwxyz";
    private static final String NUM     = "0123456789";
    private static final String SPL_CHARS   = "!@#$%^&*_=+-/";

    public static char[] generatePswd(int minLen, int maxLen, int noOfCAPSAlpha, 
            int noOfDigits, int noOfSplChars) {
        if(minLen > maxLen)
            throw new IllegalArgumentException("Min. Length > Max. Length!");
        if( (noOfCAPSAlpha + noOfDigits + noOfSplChars) > minLen )
            throw new IllegalArgumentException
            ("Min. Length should be atleast sum of (CAPS, DIGITS, SPL CHARS) Length!");
        Random rnd = new Random();
        int len = rnd.nextInt(maxLen - minLen + 1) + minLen;
        char[] pswd = new char[len];
        int index = 0;
        for (int i = 0; i < noOfCAPSAlpha; i++) {
            index = getNextIndex(rnd, len, pswd);
            pswd[index] = ALPHA_CAPS.charAt(rnd.nextInt(ALPHA_CAPS.length()));
        }
        for (int i = 0; i < noOfDigits; i++) {
            index = getNextIndex(rnd, len, pswd);
            pswd[index] = NUM.charAt(rnd.nextInt(NUM.length()));
        }
        for (int i = 0; i < noOfSplChars; i++) {
            index = getNextIndex(rnd, len, pswd);
            pswd[index] = SPL_CHARS.charAt(rnd.nextInt(SPL_CHARS.length()));
        }
        for(int i = 0; i < len; i++) {
            if(pswd[i] == 0) {
                pswd[i] = ALPHA.charAt(rnd.nextInt(ALPHA.length()));
            }
        }
        return pswd;
    }

    private static int getNextIndex(Random rnd, int len, char[] pswd) {
        int index = rnd.nextInt(len);
        while(pswd[index = rnd.nextInt(len)] != 0);
        return index;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 正则表达式:如何知道该字符串包含至少2个大写字母? - Regex: how to know that string contains at least 2 upper case letters? 随机化大写字母 - Randomize capital letters 如何将小写字母转换为大写字母 &amp; 以及将大写字母转换为小写字母 - how to convert Lower case letters to upper case letters & and upper case letters to lower case letters 我如何创建一个程序来过滤字符串中的小写和大写字母? - how do i create a program to filter out lower case and upper case letters from a string? 制作一种在字符串中查找小写字母的方法 - Making a method to find lower case letters in a string 如何在分布式系统中以相同的方式随机化两个字符串 collections? - How to randomize two String collections in the same fashion in distributed system? 如何随机化然后拆分 ArrayList<string> 分成两个偶数 ArrayList</string> - How to randomize and then split an ArrayList<String> into two even ArrayLists 如何随机化一个String数组,以便每次循环都不同 - How to randomize an array of a String so it is different every time though the loop 随机化单词中间的字母,同时保持第一个和最后一个字母不变 - Randomize the letters in the middle of the word, while keeping the first and last letters unchanged 如何手动随机播放字符串中的字母 - How to manually shuffle letters in a String
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM