diff --git a/build.gradle b/build.gradle index e7eb4ff..0866233 100644 --- a/build.gradle +++ b/build.gradle @@ -49,6 +49,8 @@ dependencies { compile 'com.h2database:h2:1.4.194' + compile 'com.google.zxing:core:3.3.0' + providedRuntime("org.springframework.boot:spring-boot-starter-tomcat") testCompile("org.springframework.boot:spring-boot-starter-test") } diff --git a/src/main/java/ch/dissem/bitmessage/server/JabitServerConfig.java b/src/main/java/ch/dissem/bitmessage/server/JabitServerConfig.java index 3d256d5..6c7c52a 100644 --- a/src/main/java/ch/dissem/bitmessage/server/JabitServerConfig.java +++ b/src/main/java/ch/dissem/bitmessage/server/JabitServerConfig.java @@ -204,6 +204,7 @@ public class JabitServerConfig { LOG.info("Using " + identity); } } + LOG.info("QR Code:\n" + Utils.qrCode(identity)); return identity; } } diff --git a/src/main/java/ch/dissem/bitmessage/server/Utils.java b/src/main/java/ch/dissem/bitmessage/server/Utils.java index 50d6a5f..fedc24f 100644 --- a/src/main/java/ch/dissem/bitmessage/server/Utils.java +++ b/src/main/java/ch/dissem/bitmessage/server/Utils.java @@ -16,16 +16,24 @@ package ch.dissem.bitmessage.server; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileWriter; -import java.io.IOException; +import ch.dissem.bitmessage.entity.BitmessageAddress; +import com.google.zxing.WriterException; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import com.google.zxing.qrcode.encoder.ByteMatrix; +import com.google.zxing.qrcode.encoder.Encoder; +import com.google.zxing.qrcode.encoder.QRCode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; import java.util.HashSet; import java.util.Scanner; import java.util.Set; import java.util.stream.Stream; public class Utils { + private static final Logger LOG = LoggerFactory.getLogger(Utils.class); + public static Set readOrCreateList(String filename, String content) { try { File file = new File(filename); @@ -76,6 +84,67 @@ public class Utils { return result; } + public static String qrCode(BitmessageAddress address) { + StringBuilder link = new StringBuilder(); + link.append("bitmessage:"); + link.append(address.getAddress()); + if (address.getAlias() != null) { + link.append("?label=").append(address.getAlias()); + } + if (address.getPubkey() != null) { + link.append(address.getAlias() == null ? '?' : '&'); + ByteArrayOutputStream pubkey = new ByteArrayOutputStream(); + try { + address.getPubkey().writeUnencrypted(pubkey); + } catch (IOException e) { + throw new RuntimeException(e); + } + // This makes the QR code quite big, so it's not active. But sometimes it might be useful: + // link.append("pubkey=").append(Base64.getUrlEncoder().encodeToString(pubkey.toByteArray())); + } + QRCode code; + try { + code = Encoder.encode(link.toString(), ErrorCorrectionLevel.L, null); + } catch (WriterException e) { + LOG.error(e.getMessage(), e); + return ""; + } + ByteMatrix matrix = code.getMatrix(); + StringBuilder result = new StringBuilder(); + for (int i=0; i<2; i++){ + for (int j=0;j 0) { + if (matrix.getHeight() > i + 1 && matrix.get(i + 1, j) > 0) { + result.append(' '); + } else { + result.append('▄'); + } + } else { + if (matrix.getHeight() > i + 1 && matrix.get(i + 1, j) > 0) { + result.append('▀'); + } else { + result.append('█'); + } + } + } + result.append("████\n"); + } + for (int i=0; i<2; i++){ + for (int j=0;j