some organisation, Base32 password generator

This commit is contained in:
minjaesong
2017-05-03 02:37:03 +09:00
parent f8435711dd
commit c1ef44c2f2
29 changed files with 367 additions and 217 deletions

View 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()
}
}

View 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
}
}

View 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)
}
}

View 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
}
}

View 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()
}
}

View 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
}
}

View 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))
}
}