mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-11 02:54:04 +09:00
some organisation, Base32 password generator
This commit is contained in:
71
src/net/torvald/terrarum/utils/CSVFetcher.kt
Normal file
71
src/net/torvald/terrarum/utils/CSVFetcher.kt
Normal file
@@ -0,0 +1,71 @@
|
||||
package net.torvald.terrarum.utils
|
||||
|
||||
import net.torvald.terrarum.ModMgr
|
||||
import org.apache.commons.csv.CSVFormat
|
||||
import org.apache.commons.csv.CSVParser
|
||||
import org.apache.commons.csv.CSVRecord
|
||||
|
||||
import java.io.IOException
|
||||
import java.io.InputStreamReader
|
||||
import java.nio.file.FileSystems
|
||||
import java.nio.file.Files
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 16-02-16.
|
||||
*/
|
||||
object CSVFetcher {
|
||||
|
||||
private var csvString: StringBuffer? = null
|
||||
|
||||
fun readFromFile(csvFilePath: String): List<org.apache.commons.csv.CSVRecord> {
|
||||
net.torvald.terrarum.utils.CSVFetcher.csvString = StringBuffer() // reset buffer every time it called
|
||||
net.torvald.terrarum.utils.CSVFetcher.readCSVasString(csvFilePath)
|
||||
|
||||
println("[CSVFetcher] Reading CSV $csvFilePath")
|
||||
|
||||
val csvParser = org.apache.commons.csv.CSVParser.parse(
|
||||
net.torvald.terrarum.utils.CSVFetcher.csvString!!.toString(),
|
||||
org.apache.commons.csv.CSVFormat.DEFAULT.withIgnoreSurroundingSpaces()
|
||||
.withHeader()
|
||||
.withIgnoreEmptyLines()
|
||||
.withDelimiter(';')
|
||||
.withCommentMarker('#')
|
||||
.withNullString("N/A")
|
||||
.withRecordSeparator('\n')
|
||||
)
|
||||
|
||||
val csvRecordList = csvParser.records
|
||||
csvParser.close()
|
||||
|
||||
return csvRecordList
|
||||
}
|
||||
|
||||
fun readFromModule(module: String, path: String) = net.torvald.terrarum.utils.CSVFetcher.readFromFile(ModMgr.getPath(module, path))
|
||||
|
||||
fun readFromString(csv: String): List<org.apache.commons.csv.CSVRecord> {
|
||||
val csvParser = org.apache.commons.csv.CSVParser.parse(
|
||||
csv,
|
||||
org.apache.commons.csv.CSVFormat.DEFAULT.withIgnoreSurroundingSpaces()
|
||||
.withHeader()
|
||||
.withIgnoreEmptyLines()
|
||||
.withDelimiter(';')
|
||||
.withCommentMarker('#')
|
||||
.withNullString("N/A")
|
||||
.withRecordSeparator('\n')
|
||||
)
|
||||
|
||||
val csvRecordList = csvParser.records
|
||||
csvParser.close()
|
||||
|
||||
return csvRecordList
|
||||
}
|
||||
|
||||
@Throws(java.io.IOException::class)
|
||||
fun readCSVasString(path: String): String {
|
||||
net.torvald.terrarum.utils.CSVFetcher.csvString = StringBuffer()
|
||||
java.nio.file.Files.lines(java.nio.file.FileSystems.getDefault().getPath(path)).forEach(
|
||||
{ s -> net.torvald.terrarum.utils.CSVFetcher.csvString!!.append("$s\n") }
|
||||
)
|
||||
return net.torvald.terrarum.utils.CSVFetcher.csvString!!.toString()
|
||||
}
|
||||
}
|
||||
65
src/net/torvald/terrarum/utils/CipherROT.kt
Normal file
65
src/net/torvald/terrarum/utils/CipherROT.kt
Normal file
@@ -0,0 +1,65 @@
|
||||
package net.torvald.terrarum.utils
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 16-03-20.
|
||||
*/
|
||||
object CipherROT {
|
||||
|
||||
const val CODE_CAP_A = 'A'.toInt()
|
||||
const val CODE_LOW_A = 'a'.toInt()
|
||||
|
||||
/**
|
||||
* ROT encryption, default setting
|
||||
*
|
||||
* * Latin alph: removes diacritics and do ROT13, string reverse, capitalised.
|
||||
* Ligatures are disassembled. Even if the target language does not have
|
||||
* certain alphabet (e.g. C in Icelandic), such alphabet will be printed anyway.
|
||||
* * Numeric: no encrypt
|
||||
*/
|
||||
fun encrypt(plaintext: String): String {
|
||||
|
||||
fun removeDiacritics(c: Char): Char {
|
||||
val normaliseMap = hashMapOf(
|
||||
Pair('À', "A"),
|
||||
Pair('Á', "A"),
|
||||
Pair('Â', "A"),
|
||||
Pair('À', "A"),
|
||||
Pair('Ã', "A"),
|
||||
Pair('Å', "A"),
|
||||
Pair('Æ', "AE"),
|
||||
Pair('Ç', "C"),
|
||||
Pair('È', "E"),
|
||||
Pair('É', "E"),
|
||||
Pair('Ê', "E"),
|
||||
Pair('Ë', "E"),
|
||||
Pair('Ì', "I"),
|
||||
Pair('Í', "I"),
|
||||
Pair('Î', "I"),
|
||||
Pair('Ï', "I"),
|
||||
Pair('Ð', "D")
|
||||
)
|
||||
throw NotImplementedError("Feature WIP")
|
||||
}
|
||||
|
||||
throw NotImplementedError("Feature WIP")
|
||||
}
|
||||
|
||||
/**
|
||||
* Note; range starts with zero
|
||||
* @param number to rotate
|
||||
* @param rotation
|
||||
* @param range size of the rotation table. 4 means (0,1,2,3)
|
||||
*/
|
||||
fun rotN(number: Int, rotation: Int, range: Int): Int {
|
||||
return if (number < range - rotation + 1) number + rotation
|
||||
else number - (range - rotation + 1)
|
||||
}
|
||||
|
||||
fun rot13(c: Char): Char {
|
||||
return if (c in 'a'..'z')
|
||||
(rotN((c.toInt() - CODE_LOW_A), 13, 26) + CODE_LOW_A).toChar()
|
||||
else if (c in 'A'..'Z')
|
||||
(rotN((c.toInt() - CODE_CAP_A), 13, 26) + CODE_CAP_A).toChar()
|
||||
else c
|
||||
}
|
||||
}
|
||||
19
src/net/torvald/terrarum/utils/Clipboard.kt
Normal file
19
src/net/torvald/terrarum/utils/Clipboard.kt
Normal file
@@ -0,0 +1,19 @@
|
||||
package net.torvald.terrarum.utils
|
||||
|
||||
import java.awt.Toolkit
|
||||
import java.awt.datatransfer.DataFlavor
|
||||
import java.awt.datatransfer.StringSelection
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 16-07-31.
|
||||
*/
|
||||
object Clipboard {
|
||||
fun fetch(): String =
|
||||
Toolkit.getDefaultToolkit().systemClipboard.getData(DataFlavor.stringFlavor) as String
|
||||
|
||||
fun paste(s: String) {
|
||||
val selection = StringSelection(s)
|
||||
val clipboard = Toolkit.getDefaultToolkit().systemClipboard
|
||||
clipboard.setContents(selection, selection)
|
||||
}
|
||||
}
|
||||
52
src/net/torvald/terrarum/utils/JsonFetcher.kt
Normal file
52
src/net/torvald/terrarum/utils/JsonFetcher.kt
Normal file
@@ -0,0 +1,52 @@
|
||||
package net.torvald.terrarum.utils
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParser
|
||||
import java.io.File
|
||||
|
||||
import java.io.IOException
|
||||
import java.nio.file.FileSystems
|
||||
import java.nio.file.Files
|
||||
import java.util.ArrayList
|
||||
import java.util.function.Consumer
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 16-02-15.
|
||||
*/
|
||||
object JsonFetcher {
|
||||
|
||||
private var jsonString: StringBuffer? = null
|
||||
|
||||
@Throws(java.io.IOException::class)
|
||||
operator fun invoke(jsonFilePath: String): com.google.gson.JsonObject {
|
||||
net.torvald.terrarum.utils.JsonFetcher.jsonString = StringBuffer() // reset buffer every time it called
|
||||
net.torvald.terrarum.utils.JsonFetcher.readJsonFileAsString(jsonFilePath)
|
||||
|
||||
println("[JsonFetcher] Reading JSON $jsonFilePath")
|
||||
|
||||
val jsonParser = com.google.gson.JsonParser()
|
||||
val jsonObj = jsonParser.parse(net.torvald.terrarum.utils.JsonFetcher.jsonString!!.toString()).asJsonObject
|
||||
|
||||
return jsonObj
|
||||
}
|
||||
|
||||
@Throws(java.io.IOException::class)
|
||||
operator fun invoke(jsonFile: java.io.File): com.google.gson.JsonObject {
|
||||
net.torvald.terrarum.utils.JsonFetcher.jsonString = StringBuffer() // reset buffer every time it called
|
||||
net.torvald.terrarum.utils.JsonFetcher.readJsonFileAsString(jsonFile.canonicalPath)
|
||||
|
||||
println("[JsonFetcher] Reading JSON ${jsonFile.path}")
|
||||
|
||||
val jsonParser = com.google.gson.JsonParser()
|
||||
val jsonObj = jsonParser.parse(net.torvald.terrarum.utils.JsonFetcher.jsonString!!.toString()).asJsonObject
|
||||
|
||||
return jsonObj
|
||||
}
|
||||
|
||||
@Throws(java.io.IOException::class)
|
||||
private fun readJsonFileAsString(path: String) {
|
||||
java.nio.file.Files.lines(java.nio.file.FileSystems.getDefault().getPath(path)).forEach(
|
||||
{ net.torvald.terrarum.utils.JsonFetcher.jsonString!!.append(it) }
|
||||
) // JSON does not require line break
|
||||
}
|
||||
}
|
||||
43
src/net/torvald/terrarum/utils/JsonWriter.kt
Normal file
43
src/net/torvald/terrarum/utils/JsonWriter.kt
Normal file
@@ -0,0 +1,43 @@
|
||||
package net.torvald.terrarum.utils
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonObject
|
||||
|
||||
import java.io.FileWriter
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 16-03-04.
|
||||
*/
|
||||
object JsonWriter {
|
||||
|
||||
/**
|
||||
* serialise a class to the file as JSON, using Google GSON.
|
||||
*
|
||||
* @param c: a class
|
||||
* @param path: path to write a file
|
||||
*/
|
||||
@Throws(java.io.IOException::class)
|
||||
fun writeToFile(c: Any, path: String) {
|
||||
val classElem = com.google.gson.Gson().toJsonTree(c)
|
||||
val jsonString = classElem.toString()
|
||||
val writer = java.io.FileWriter(path)
|
||||
writer.write(jsonString)
|
||||
writer.close()
|
||||
}
|
||||
|
||||
/**
|
||||
* serialise JsonObject to the file as JSON, using Google GSON.
|
||||
*
|
||||
* @param jsonObject
|
||||
* @param path: path to write a file
|
||||
*/
|
||||
@Throws(java.io.IOException::class)
|
||||
fun writeToFile(jsonObject: com.google.gson.JsonObject, path: String) {
|
||||
val writer = java.io.FileWriter(path)
|
||||
writer.write(jsonObject.toString())
|
||||
writer.close()
|
||||
}
|
||||
|
||||
}
|
||||
150
src/net/torvald/terrarum/utils/PasswordBase32.kt
Normal file
150
src/net/torvald/terrarum/utils/PasswordBase32.kt
Normal file
@@ -0,0 +1,150 @@
|
||||
package net.torvald.terrarum.utils
|
||||
|
||||
import kotlin.experimental.xor
|
||||
|
||||
|
||||
/**
|
||||
* Old-school passworld system using Base32
|
||||
*
|
||||
* Created by minjaesong on 2017-05-02.
|
||||
*/
|
||||
object PasswordBase32 {
|
||||
|
||||
private val stringSet = "YBNDRFG8EJKMCPQXOT+VWIS2A345H769="
|
||||
|
||||
private val substituteSet = hashMapOf(
|
||||
Pair('0', 'O'),
|
||||
Pair('1', 'I'),
|
||||
Pair('Z', '2')
|
||||
)
|
||||
|
||||
/*
|
||||
0 x
|
||||
1 6
|
||||
2 4
|
||||
3 3
|
||||
4 1
|
||||
*/
|
||||
val padLen = arrayOf(0, 6, 4, 3, 1)
|
||||
private val nullPw = byteArrayOf(0.toByte())
|
||||
|
||||
|
||||
private fun encodeToLetters(byteArray: ByteArray, password: ByteArray): IntArray {
|
||||
val out = ArrayList<Int>()
|
||||
|
||||
fun get(i: Int) = byteArray[i] xor (password[i % password.size])
|
||||
|
||||
|
||||
/*
|
||||
5 Bytes -> 8 Letters
|
||||
|
||||
0000 0000 | 1111 1111 | 2222 2222 | 3333 3333 | 4444 4444
|
||||
AAAA ABBB | BBCC CCCD | DDDD EEEE | EFFF FFGG | GGGH HHHH
|
||||
*/
|
||||
|
||||
// non-pads
|
||||
(0..byteArray.lastIndex - 5 step 5).forEach {
|
||||
/* A */ out.add(get(it).toInt().and(0xF8).ushr(3))
|
||||
/* B */ out.add(get(it).toInt().and(7).shl(2) or get(it+1).toInt().and(0xC0).ushr(6))
|
||||
/* C */ out.add(get(it+1).toInt().and(0x3E).ushr(1))
|
||||
/* D */ out.add(get(it+1).toInt().and(1).shl(4) or get(it+2).toInt().and(0xF0).ushr(4))
|
||||
/* E */ out.add(get(it+2).toInt().and(0xF).shl(1) or get(it+3).toInt().and(0x80).ushr(7))
|
||||
/* F */ out.add(get(it+3).toInt().and(0x7C).ushr(2))
|
||||
/* G */ out.add(get(it+3).toInt().and(3).shl(3) or get(it+4).toInt().and(0xE0).ushr(5))
|
||||
/* H */ out.add(get(it+4).toInt().and(0x1F))
|
||||
}
|
||||
// pads
|
||||
val residue = byteArray.size % 5
|
||||
if (residue != 0){
|
||||
|
||||
val it = (byteArray.size / 5) * 5 // dark magic of integer division, let's hope the compiler won't "optimise" this...
|
||||
|
||||
when (residue) {
|
||||
1 -> {
|
||||
/* A */ out.add(get(it).toInt().and(0xF8).ushr(3))
|
||||
/* B */ out.add(get(it).toInt().and(7).shl(2))
|
||||
}
|
||||
2 -> {
|
||||
/* A */ out.add(get(it).toInt().and(0xF8).ushr(3))
|
||||
/* B */ out.add(get(it).toInt().and(7).shl(2) or get(it+1).toInt().and(0xC0).ushr(6))
|
||||
/* C */ out.add(get(it+1).toInt().and(0x3E).ushr(1))
|
||||
/* D */ out.add(get(it+1).toInt().and(1).shl(4))
|
||||
}
|
||||
3 -> {
|
||||
/* A */ out.add(get(it).toInt().and(0xF8).ushr(3))
|
||||
/* B */ out.add(get(it).toInt().and(7).shl(2) or get(it+1).toInt().and(0xC0).ushr(6))
|
||||
/* C */ out.add(get(it+1).toInt().and(0x3E).ushr(1))
|
||||
/* D */ out.add(get(it+1).toInt().and(1).shl(4) or get(it+2).toInt().and(0xF0).ushr(4))
|
||||
/* E */ out.add(get(it+2).toInt().and(0xF).shl(1))
|
||||
}
|
||||
4 -> {
|
||||
/* A */ out.add(get(it).toInt().and(0xF8).ushr(3))
|
||||
/* B */ out.add(get(it).toInt().and(7).shl(2) or get(it+1).toInt().and(0xC0).ushr(6))
|
||||
/* C */ out.add(get(it+1).toInt().and(0x3E).ushr(1))
|
||||
/* D */ out.add(get(it+1).toInt().and(1).shl(4) or get(it+2).toInt().and(0xF0).ushr(4))
|
||||
/* E */ out.add(get(it+2).toInt().and(0xF).shl(1) or get(it+3).toInt().and(0x80).ushr(7))
|
||||
/* F */ out.add(get(it+3).toInt().and(0x7C).ushr(2))
|
||||
/* G */ out.add(get(it+3).toInt().and(3).shl(3))
|
||||
}
|
||||
}
|
||||
|
||||
// append padding
|
||||
kotlin.repeat(padLen[residue], { out.add(32) })
|
||||
}
|
||||
|
||||
return out.toIntArray()
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param bytes size of multiple of five (5, 10, 15, 20, ...) is highly recommended to prevent
|
||||
* lengthy padding
|
||||
* @param password to encode resulting string using XOR Cipher to prevent unexperienced kids
|
||||
* from doing naughty things. Longer, the better.
|
||||
*/
|
||||
fun encode(bytes: ByteArray, password: ByteArray = nullPw): String {
|
||||
val plaintext = encodeToLetters(bytes, password)
|
||||
val sb = StringBuilder()
|
||||
plaintext.forEach { sb.append(stringSet[it]) }
|
||||
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param outByteLength expected length of your decoded password. It is always a good idea to
|
||||
* suspect user inputs and sanitise them.
|
||||
*/
|
||||
fun decode(input: String, outByteLength: Int, password: ByteArray = nullPw): ByteArray {
|
||||
val buffer = ByteArray(outByteLength)
|
||||
var appendCount = 0
|
||||
var input = input.toUpperCase()
|
||||
substituteSet.forEach { from, to ->
|
||||
input = input.replace(from, to)
|
||||
}
|
||||
|
||||
fun append(byte: Int) {
|
||||
buffer[appendCount] = byte.toByte() xor (password[appendCount % password.size])
|
||||
appendCount++
|
||||
}
|
||||
fun sbyteOf(i: Int) = stringSet.indexOf(input[i]).and(0x1F)
|
||||
|
||||
try {
|
||||
/*
|
||||
8 Letters -> 5 Bytes
|
||||
|
||||
0000 0000 | 1111 1111 | 2222 2222 | 3333 3333 | 4444 4444
|
||||
AAAA ABBB | BBCC CCCD | DDDD EEEE | EFFF FFGG | GGGH HHHH
|
||||
*/
|
||||
(0..input.lastIndex.plus(8) step 8).forEach {
|
||||
/* 0 */ append(sbyteOf(it+0).shl(3) or sbyteOf(it+1).ushr(2))
|
||||
/* 1 */ append(sbyteOf(it+1).shl(6) or sbyteOf(it+2).shl(1) or sbyteOf(it+3).ushr(4))
|
||||
/* 2 */ append(sbyteOf(it+3).shl(4) or sbyteOf(it+4).ushr(1))
|
||||
/* 3 */ append(sbyteOf(it+4).shl(7) or sbyteOf(it+5).shl(2) or sbyteOf(it+6).ushr(3))
|
||||
/* 4 */ append(sbyteOf(it+6).shl(5) or sbyteOf(it+7))
|
||||
}
|
||||
}
|
||||
catch (endOfStream: ArrayIndexOutOfBoundsException) { }
|
||||
|
||||
return buffer
|
||||
}
|
||||
}
|
||||
49
src/net/torvald/terrarum/utils/RasterWriter.kt
Normal file
49
src/net/torvald/terrarum/utils/RasterWriter.kt
Normal file
@@ -0,0 +1,49 @@
|
||||
package net.torvald.terrarum.utils
|
||||
|
||||
import javax.imageio.ImageIO
|
||||
import java.awt.*
|
||||
import java.awt.color.ColorSpace
|
||||
import java.awt.image.*
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 16-03-04.
|
||||
*/
|
||||
object RasterWriter {
|
||||
|
||||
val BANDOFFSET_RGB = intArrayOf(0, 1, 2)
|
||||
val BANDOFFSET_RGBA = intArrayOf(0, 1, 2, 3)
|
||||
val BANDOFFSET_ARGB = intArrayOf(3, 0, 1, 2)
|
||||
val BANDOFFSET_MONO = intArrayOf(0)
|
||||
|
||||
val COLORSPACE_SRGB = java.awt.color.ColorSpace.CS_sRGB
|
||||
val COLORSPACE_GRAY = java.awt.color.ColorSpace.CS_GRAY
|
||||
val COLORSPACE_GREY = net.torvald.terrarum.utils.RasterWriter.COLORSPACE_GRAY
|
||||
val COLORSPACE_CIEXYZ = java.awt.color.ColorSpace.CS_CIEXYZ
|
||||
val COLORSPACE_RGB_LINEAR_GAMMA = java.awt.color.ColorSpace.CS_LINEAR_RGB
|
||||
|
||||
@Throws(java.io.IOException::class)
|
||||
fun writePNG_RGB(w: Int, h: Int, rasterData: ByteArray, path: String) {
|
||||
net.torvald.terrarum.utils.RasterWriter.writePNG(w, h, rasterData, BANDOFFSET_RGB, COLORSPACE_SRGB, path)
|
||||
}
|
||||
|
||||
@Throws(java.io.IOException::class)
|
||||
fun writePNG_Mono(w: Int, h: Int, rasterData: ByteArray, path: String) {
|
||||
net.torvald.terrarum.utils.RasterWriter.writePNG(w, h, rasterData, BANDOFFSET_MONO, COLORSPACE_GREY, path)
|
||||
}
|
||||
|
||||
@Throws(java.io.IOException::class)
|
||||
fun writePNG(w: Int, h: Int, rasterData: ByteArray, bandOffsets: IntArray, awt_colorspace: Int, path: String) {
|
||||
val buffer = java.awt.image.DataBufferByte(rasterData, rasterData.size)
|
||||
val raster = java.awt.image.Raster.createInterleavedRaster(
|
||||
buffer, w, h, bandOffsets.size * w, bandOffsets.size, bandOffsets, null)
|
||||
|
||||
val colorModel = java.awt.image.ComponentColorModel(java.awt.color.ColorSpace.getInstance(awt_colorspace), false, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE)
|
||||
|
||||
val image = java.awt.image.BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied, null)
|
||||
|
||||
javax.imageio.ImageIO.write(image, "PNG", java.io.File(path))
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user