1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.core.joran.spi;
15
16 import java.util.ArrayList;
17 import java.util.List;
18
19 public class CaseCombinator {
20
21 List<String> combinations(String in) {
22 int length = in.length();
23 List<String> permutationsList = new ArrayList<String>();
24
25 int totalCombinations = computeTotalNumerOfCombinations(in, length);
26
27 for (int j = 0; j < totalCombinations; j++) {
28 StringBuilder newCombination = new StringBuilder();
29 int pos = 0;
30 for (int i = 0; i < length; i++) {
31 char c = in.charAt(i);
32 if (isEnglishLetter(c)) {
33 c = permute(c, j, pos);
34 pos++;
35 }
36 newCombination.append(c);
37 }
38 permutationsList.add(newCombination.toString());
39 }
40 return permutationsList;
41
42 }
43
44 private char permute(char c, int permutation, int position) {
45 int mask = 1 << position;
46 boolean shouldBeInUpperCase = (permutation & mask) != 0;
47 boolean isEffectivelyUpperCase = isUpperCase(c);
48 if (shouldBeInUpperCase && !isEffectivelyUpperCase)
49 return toUpperCase(c);
50 if (!shouldBeInUpperCase && isEffectivelyUpperCase)
51 return toLowerCase(c);
52 return c;
53 }
54
55 private int computeTotalNumerOfCombinations(String in, int length) {
56 int count = 0;
57 for (int i = 0; i < length; i++) {
58 char c = in.charAt(i);
59 if (isEnglishLetter(c))
60 count++;
61 }
62
63 return (1 << count);
64 }
65
66 private char toUpperCase(char c) {
67 if ('A' <= c && c <= 'Z') {
68 return c;
69 }
70 if ('a' <= c && c <= 'z') {
71 return (char) ((int) c + 'A' - 'a');
72 }
73
74 return c;
75 }
76
77 private char toLowerCase(char c) {
78 if ('a' <= c && c <= 'z') {
79 return c;
80 }
81 if ('A' <= c && c <= 'Z') {
82 return (char) ((int) c + 'a' - 'A');
83 }
84
85 return c;
86 }
87
88 private boolean isEnglishLetter(char c) {
89 if ('a' <= c && c <= 'z')
90 return true;
91
92 if ('A' <= c && c <= 'Z')
93 return true;
94 return false;
95 }
96
97 private boolean isUpperCase(char c) {
98 return ('A' <= c && c <= 'Z');
99 }
100 }