blob: 32689fc1d722e5043b0470580e6f9c748d6ff220 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
package ixee.cryptopals.utils
import ByteUtils._
import FunctionUtils._
object ConversionUtils {
def hexStr2Bytes(s: String): Seq[Byte] =
padToByte(s).grouped(2).map(byteStr2Byte).toStream.force
def byteStr2Byte(str: String): Byte =
charSeq2Byte(str.toSeq)
def charSeq2Byte(seq: Seq[Char]): Byte =
seq.map(octet2nibble).reduce(joinNibbles)
def joinNibbles(a: Byte, b: Byte): Byte =
((a @<< 4) @+ b)
def padToByte(s: String): String =
if (s.length % 2 != 0) "0" + s else s
def octet2nibble(c: Char): Byte = {
(c.toLower match {
case c if c >= 'a' && c <= 'f' =>
(c - 'a') + 10.toByte
case c if c >= '0' && c <= '9' =>
c - '0'
case _ =>
throw new IllegalArgumentException(s"Invalid hexadecimal character: $c")
}).toByte
}
def hexStr2Base64String(s: String): String = {
import io.github.marklister.base64.Base64._
hexStr2Bytes(s).toArray.toBase64
}
implicit class RichSeqByte(seq: Seq[Byte]) {
def to[T : SizedNumeric : BitOps]: T = {
val numeric = implicitly[SizedNumeric[T]]
if(seq.length < numeric.byteSize) {
throw new RuntimeException("Byte input is not long enough")
}
var out: Long = seq(0)
for(i <- 1 until numeric.byteSize) {
out << 8
out = seq(i) | out
}
numeric.fromLong(out)
}
def hex: String =
seq.map(_.hex).reduceLeft(_ + _)
def asAscii: String =
new String(seq.toArray)
}
implicit class RichStringBytes(s: String) {
def asBytes = s.toSeq.map(_.toByte)
def asByteStream = s.asBytes.toStream
def asRepeatedBytes(count: Int) =
Stream.continually(s.asBytes).flatten.take(count)
}
// TODO: tailrec this, get rid of for
def toByteSeq[T : SizedNumeric : BitOps](x: T): Seq[Byte] = {
val buf = new Array[Byte](x.byteSize)
for(i <- 0 until x.byteSize) {
val shiftAmount = (x.byteSize - i - 1) << 3
buf(i) = (x @>>> shiftAmount).truncatedTo[Byte]
}
buf.toSeq
}
def toBinaryString[T : SizedNumeric](x: T)(implicit a: BitOps[T]): String = {
val buf = new StringBuilder(x.bitSize)
for(i <- 0 until x.bitSize) {
val shiftAmount: Int = x.bitSize - i - 1
buf.append((x @>>> shiftAmount) @& 0x01.liftedTo[T])
}
buf.toString()
}
}
|