aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo/geocaching/utils
diff options
context:
space:
mode:
authorBananeweizen <bananeweizen@gmx.de>2011-09-16 18:44:54 +0200
committerBananeweizen <bananeweizen@gmx.de>2011-09-16 18:44:54 +0200
commite94489086517a78de488cb9580bba756bd86b30b (patch)
treea1aee56794f93f8b680180118c20d6e0abba2801 /main/src/cgeo/geocaching/utils
parentf571eb3981c710907e8110e7c185e2d5a9fc8fa3 (diff)
downloadcgeo-e94489086517a78de488cb9580bba756bd86b30b.zip
cgeo-e94489086517a78de488cb9580bba756bd86b30b.tar.gz
cgeo-e94489086517a78de488cb9580bba756bd86b30b.tar.bz2
fix #473: ROT13 on String or Spannable, including new test
Diffstat (limited to 'main/src/cgeo/geocaching/utils')
-rw-r--r--main/src/cgeo/geocaching/utils/CryptUtils.java113
1 files changed, 113 insertions, 0 deletions
diff --git a/main/src/cgeo/geocaching/utils/CryptUtils.java b/main/src/cgeo/geocaching/utils/CryptUtils.java
new file mode 100644
index 0000000..a2927aa
--- /dev/null
+++ b/main/src/cgeo/geocaching/utils/CryptUtils.java
@@ -0,0 +1,113 @@
+package cgeo.geocaching.utils;
+
+import cgeo.geocaching.cgSettings;
+
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
+import android.util.Log;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+public final class CryptUtils {
+ public static String rot13(String text) {
+ if (text == null) {
+ return "";
+ }
+ final StringBuilder result = new StringBuilder();
+ // plaintext flag (do not convert)
+ boolean plaintext = false;
+
+ final int length = text.length();
+ int c;
+ int capitalized;
+ for (int index = 0; index < length; index++) {
+ c = text.charAt(index);
+ if (c == '[') {
+ plaintext = true;
+ } else if (c == ']') {
+ plaintext = false;
+ } else if (!plaintext) {
+ capitalized = c & 32;
+ c &= ~capitalized;
+ c = ((c >= 'A') && (c <= 'Z') ? ((c - 'A' + 13) % 26 + 'A') : c)
+ | capitalized;
+ }
+ result.append((char) c);
+ }
+ return result.toString();
+ }
+
+ public static String md5(String text) {
+ String hashed = "";
+
+ try {
+ final MessageDigest digest = MessageDigest.getInstance("MD5");
+ digest.update(text.getBytes(), 0, text.length());
+ hashed = new BigInteger(1, digest.digest()).toString(16);
+ } catch (Exception e) {
+ Log.e(cgSettings.tag, "cgBase.md5: " + e.toString());
+ }
+
+ return hashed;
+ }
+
+ public static String sha1(String text) {
+ String hashed = "";
+
+ try {
+ final MessageDigest digest = MessageDigest.getInstance("SHA-1");
+ digest.update(text.getBytes(), 0, text.length());
+ hashed = new BigInteger(1, digest.digest()).toString(16);
+ } catch (Exception e) {
+ Log.e(cgSettings.tag, "cgBase.sha1: " + e.toString());
+ }
+
+ return hashed;
+ }
+
+ public static byte[] hashHmac(String text, String salt) {
+ byte[] macBytes = {};
+
+ try {
+ final SecretKeySpec secretKeySpec = new SecretKeySpec(salt.getBytes(), "HmacSHA1");
+ final Mac mac = Mac.getInstance("HmacSHA1");
+ mac.init(secretKeySpec);
+ macBytes = mac.doFinal(text.getBytes());
+ } catch (Exception e) {
+ Log.e(cgSettings.tag, "cgBase.hashHmac: " + e.toString());
+ }
+
+ return macBytes;
+ }
+
+ public static CharSequence rot13(final Spannable span) {
+ // I needed to re-implement the rot13(String) encryption here because we must work on
+ // a SpannableStringBuilder instead of the pure text and we must replace each character inline.
+ // Otherwise we loose all the images, colors and so on...
+ final SpannableStringBuilder buffer = new SpannableStringBuilder(span);
+ boolean plaintext = false;
+
+ final int length = span.length();
+ int c;
+ int capitalized;
+ for (int index = 0; index < length; index++) {
+ c = span.charAt(index);
+ if (c == '[') {
+ plaintext = true;
+ } else if (c == ']') {
+ plaintext = false;
+ } else if (!plaintext) {
+ capitalized = c & 32;
+ c &= ~capitalized;
+ c = ((c >= 'A') && (c <= 'Z') ? ((c - 'A' + 13) % 26 + 'A') : c)
+ | capitalized;
+ }
+ buffer.replace(index, index + 1, String.valueOf((char) c));
+ }
+ return buffer;
+ }
+}