実装
@Composable
fun PasswordGeneratorView(modifier: Modifier = Modifier) {
var password by remember { mutableStateOf("") }
var passwordLength by remember { mutableStateOf(12) }
var includeUppercase by remember { mutableStateOf(true) }
var includeLowercase by remember { mutableStateOf(true) }
var includeNumbers by remember { mutableStateOf(true) }
var includeSymbols by remember { mutableStateOf(true) }
val clipboardManager = LocalClipboardManager.current
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
Text("Password Generator", style = MaterialTheme.typography.displaySmall)
Row(verticalAlignment = Alignment.CenterVertically) {
Text("Length: $passwordLength")
Slider(
value = passwordLength.toFloat(),
onValueChange = { passwordLength = it.toInt() },
valueRange = 8f..32f
)
}
PasswordCheckBoxView(includeUppercase, includeLowercase, includeNumbers, includeSymbols)
Button(onClick = {
password = generatePassword(
length = passwordLength,
includeUppercase = includeUppercase,
includeLowercase = includeLowercase,
includeNumbers = includeNumbers,
includeSymbols = includeSymbols
)
}) {
Text("Generate Password")
}
if (password.isNotEmpty()) {
GeneratedPasswordDetailView(password, clipboardManager)
}
}
}
@Composable
private fun GeneratedPasswordDetailView(
password: String,
clipboardManager: ClipboardManager
) {
Row(verticalAlignment = Alignment.CenterVertically) {
OutlinedTextField(
value = password,
onValueChange = {},
readOnly = true,
modifier = Modifier.weight(1f)
)
IconButton(onClick = {
clipboardManager.setText(AnnotatedString(password))
}) {
Icon(
imageVector = Icons.Filled.Share,
contentDescription = null
)
}
}
Text("Strength: ${getPasswordStrength(password)}")
}
@Composable
private fun PasswordCheckBoxView(
includeUppercase: Boolean,
includeLowercase: Boolean,
includeNumbers: Boolean,
includeSymbols: Boolean
) {
var includeUppercase1 = includeUppercase
var includeLowercase1 = includeLowercase
var includeNumbers1 = includeNumbers
var includeSymbols1 = includeSymbols
Row {
Checkbox(
checked = includeUppercase1,
onCheckedChange = { includeUppercase1 = it }
)
Text(text = "Uppercase")
}
Row {
Checkbox(
checked = includeLowercase1,
onCheckedChange = { includeLowercase1 = it }
)
Text(text = "Lowercase")
}
Row {
Checkbox(
checked = includeNumbers1,
onCheckedChange = { includeNumbers1 = it }
)
Text(text = "Numbers")
}
Row {
Checkbox(
checked = includeSymbols1,
onCheckedChange = { includeSymbols1 = it }
)
Text(text = "Symbols")
}
}
private fun generatePassword(
length: Int,
includeUppercase: Boolean,
includeLowercase: Boolean,
includeNumbers: Boolean,
includeSymbols: Boolean,
): String {
val uppercaseChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
val lowercaseChars = "abcdefghijklmnopqrstuvwxyz"
val numberChars = "0123456789"
val symbolChars = "!@#$%^&*()-_=+[]{}|;:'\",.<>/?`~"
var allowedChars = ""
if (includeUppercase) allowedChars += uppercaseChars
if (includeLowercase) allowedChars += lowercaseChars
if (includeNumbers) allowedChars += numberChars
if (includeSymbols) allowedChars += symbolChars
// 使用可能な文字がない場合は空文字列を返す
if (allowedChars.isEmpty()) return ""
return (1..length) // 1からlengthまでの範囲でループ
.map { allowedChars[Random.nextInt(allowedChars.length)] }
.joinToString("") // 選択された文字を結合して文字列にする
}
private fun getPasswordStrength(password: String): String {
val strength = when {
password.length < 8 -> "Weak"
password.length < 12 -> "Medium"
else -> "Strong"
}
return strength
}