diff --git a/app/src/main/java/awais/instagrabber/utils/PasswordUtils.kt b/app/src/main/java/awais/instagrabber/utils/PasswordUtils.kt index 2cc380bc..2d4b13c6 100644 --- a/app/src/main/java/awais/instagrabber/utils/PasswordUtils.kt +++ b/app/src/main/java/awais/instagrabber/utils/PasswordUtils.kt @@ -1,47 +1,52 @@ -package awais.instagrabber.utils; +package awais.instagrabber.utils -import android.util.Base64; +import android.util.Base64 +import java.security.GeneralSecurityException +import java.security.InvalidAlgorithmParameterException +import java.security.InvalidKeyException +import java.security.NoSuchAlgorithmException +import javax.crypto.BadPaddingException +import javax.crypto.Cipher +import javax.crypto.IllegalBlockSizeException +import javax.crypto.NoSuchPaddingException +import javax.crypto.spec.IvParameterSpec +import javax.crypto.spec.SecretKeySpec -import androidx.annotation.NonNull; - -import java.security.GeneralSecurityException; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; - -public final class PasswordUtils { - private static final String cipherAlgo = "AES"; - private static final String cipherTran = "AES/CBC/PKCS5Padding"; - - public static byte[] dec(final String encrypted, final byte[] keyValue) throws Exception { - try { - final Cipher cipher = Cipher.getInstance(cipherTran); - final SecretKeySpec secretKey = new SecretKeySpec(keyValue, cipherAlgo); - cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(new byte[16])); - return cipher.doFinal(Base64.decode(encrypted, Base64.DEFAULT | Base64.NO_PADDING | Base64.NO_WRAP)); - } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidAlgorithmParameterException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException e) { - throw new IncorrectPasswordException(e); +object PasswordUtils { + private const val cipherAlgo = "AES" + private const val cipherTran = "AES/CBC/PKCS5Padding" + @JvmStatic + @Throws(Exception::class) + fun dec(encrypted: String?, keyValue: ByteArray?): ByteArray { + return try { + val cipher = Cipher.getInstance(cipherTran) + val secretKey = SecretKeySpec(keyValue, cipherAlgo) + cipher.init(Cipher.DECRYPT_MODE, secretKey, IvParameterSpec(ByteArray(16))) + cipher.doFinal(Base64.decode(encrypted, Base64.DEFAULT or Base64.NO_PADDING or Base64.NO_WRAP)) + } catch (e: NoSuchAlgorithmException) { + throw IncorrectPasswordException(e) + } catch (e: NoSuchPaddingException) { + throw IncorrectPasswordException(e) + } catch (e: InvalidAlgorithmParameterException) { + throw IncorrectPasswordException(e) + } catch (e: InvalidKeyException) { + throw IncorrectPasswordException(e) + } catch (e: BadPaddingException) { + throw IncorrectPasswordException(e) + } catch (e: IllegalBlockSizeException) { + throw IncorrectPasswordException(e) } } - public static byte[] enc(@NonNull final String str, final byte[] keyValue) throws Exception { - final Cipher cipher = Cipher.getInstance(cipherTran); - final SecretKeySpec secretKey = new SecretKeySpec(keyValue, cipherAlgo); - cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(new byte[16])); - final byte[] bytes = cipher.doFinal(str.getBytes()); - return Base64.encode(bytes, Base64.DEFAULT | Base64.NO_PADDING | Base64.NO_WRAP); + @JvmStatic + @Throws(Exception::class) + fun enc(str: String, keyValue: ByteArray?): ByteArray { + val cipher = Cipher.getInstance(cipherTran) + val secretKey = SecretKeySpec(keyValue, cipherAlgo) + cipher.init(Cipher.ENCRYPT_MODE, secretKey, IvParameterSpec(ByteArray(16))) + val bytes = cipher.doFinal(str.toByteArray()) + return Base64.encode(bytes, Base64.DEFAULT or Base64.NO_PADDING or Base64.NO_WRAP) } - public static class IncorrectPasswordException extends Exception { - public IncorrectPasswordException(final GeneralSecurityException e) { - super(e); - } - } -} + class IncorrectPasswordException(e: GeneralSecurityException?) : Exception(e) +} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/utils/TextUtils.kt b/app/src/main/java/awais/instagrabber/utils/TextUtils.kt index 5df3ac08..598cabdf 100644 --- a/app/src/main/java/awais/instagrabber/utils/TextUtils.kt +++ b/app/src/main/java/awais/instagrabber/utils/TextUtils.kt @@ -1,122 +1,75 @@ -package awais.instagrabber.utils; +package awais.instagrabber.utils -import android.content.Context; -import android.text.SpannableString; -import android.text.format.DateFormat; -import android.text.format.DateUtils; -import android.text.style.URLSpan; -import android.util.Patterns; +import android.content.Context +import android.text.format.DateFormat +import android.text.format.DateUtils +import android.util.Patterns +import java.util.* -import androidx.annotation.NonNull; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.Locale; -import java.util.regex.Matcher; -import java.util.stream.Collectors; - -public final class TextUtils { - // extracted from String class - public static int indexOfChar(@NonNull final CharSequence sequence, final int ch, final int startIndex) { - final int max = sequence.length(); - if (startIndex < max) { - if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { - for (int i = startIndex; i < max; i++) if (sequence.charAt(i) == ch) return i; - } else if (Character.isValidCodePoint(ch)) { - final char hi = (char) ((ch >>> 10) + (Character.MIN_HIGH_SURROGATE - (Character.MIN_SUPPLEMENTARY_CODE_POINT >>> 10))); - final char lo = (char) ((ch & 0x3ff) + Character.MIN_LOW_SURROGATE); - for (int i = startIndex; i < max; i++) - if (sequence.charAt(i) == hi && sequence.charAt(i + 1) == lo) return i; - } +object TextUtils { + @JvmStatic + fun isEmpty(charSequence: CharSequence?): Boolean { + if (charSequence == null || charSequence.length < 1) return true + if (charSequence is String) { + var str = charSequence + if ("" == str || "null" == str || str.isEmpty()) return true + str = str.trim { it <= ' ' } + return "" == str || "null" == str || str.isEmpty() } - return -1; + return "null".contentEquals(charSequence) || "".contentEquals(charSequence) } - public static CharSequence getSpannableUrl(final String url) { - if (isEmpty(url)) return url; - final int httpIndex = url.indexOf("http:"); - final int httpsIndex = url.indexOf("https:"); - if (httpIndex == -1 && httpsIndex == -1) return url; - - final int length = url.length(); - - final int startIndex = httpIndex != -1 ? httpIndex : httpsIndex; - final int spaceIndex = url.indexOf(' ', startIndex + 1); - - final int endIndex = (spaceIndex != -1 ? spaceIndex : length); - - final String extractUrl = url.substring(startIndex, Math.min(length, endIndex)); - - final SpannableString spannableString = new SpannableString(url); - spannableString.setSpan(new URLSpan(extractUrl), startIndex, endIndex, 0); - - return spannableString; - } - - public static boolean isEmpty(final CharSequence charSequence) { - if (charSequence == null || charSequence.length() < 1) return true; - if (charSequence instanceof String) { - String str = (String) charSequence; - if ("".equals(str) || "null".equals(str) || str.isEmpty()) return true; - str = str.trim(); - return "".equals(str) || "null".equals(str) || str.isEmpty(); - } - return "null".contentEquals(charSequence) || "".contentEquals(charSequence); - } - - public static String millisToTimeString(final long millis) { - return millisToTimeString(millis, false); - } - - public static String millisToTimeString(final long millis, final boolean includeHoursAlways) { - final int sec = (int) (millis / 1000) % 60; - int min = (int) (millis / (1000 * 60)); + @JvmStatic + @JvmOverloads + fun millisToTimeString(millis: Long, includeHoursAlways: Boolean = false): String { + val sec = (millis / 1000).toInt() % 60 + var min = (millis / (1000 * 60)).toInt() if (min >= 60) { - min = (int) ((millis / (1000 * 60)) % 60); - final int hr = (int) ((millis / (1000 * 60 * 60)) % 24); - return String.format(Locale.ENGLISH, "%02d:%02d:%02d", hr, min, sec); + min = (millis / (1000 * 60) % 60).toInt() + val hr = (millis / (1000 * 60 * 60) % 24).toInt() + return String.format(Locale.ENGLISH, "%02d:%02d:%02d", hr, min, sec) } - if (includeHoursAlways) { - return String.format(Locale.ENGLISH, "%02d:%02d:%02d", 0, min, sec); - } - return String.format(Locale.ENGLISH, "%02d:%02d", min, sec); + return if (includeHoursAlways) { + String.format(Locale.ENGLISH, "%02d:%02d:%02d", 0, min, sec) + } else String.format(Locale.ENGLISH, "%02d:%02d", min, sec) } - public static String getRelativeDateTimeString(final Context context, final long from) { - final Date now = new Date(); - final Date then = new Date(from); - int days = daysBetween(from, now.getTime()); - if (days == 0) { - return DateFormat.getTimeFormat(context).format(then); - } - return DateFormat.getDateFormat(context).format(then); + @JvmStatic + fun getRelativeDateTimeString(context: Context?, from: Long): String { + val now = Date() + val then = Date(from) + val days = daysBetween(from, now.time) + return if (days == 0) { + DateFormat.getTimeFormat(context).format(then) + } else DateFormat.getDateFormat(context).format(then) } - private static int daysBetween(long d1, long d2) { - return (int) ((d2 - d1) / DateUtils.DAY_IN_MILLIS); + private fun daysBetween(d1: Long, d2: Long): Int { + return ((d2 - d1) / DateUtils.DAY_IN_MILLIS).toInt() } - public static List extractUrls(final String text) { - if (isEmpty(text)) return Collections.emptyList(); - final Matcher matcher = Patterns.WEB_URL.matcher(text); - final List urls = new ArrayList<>(); + @JvmStatic + fun extractUrls(text: String?): List { + if (isEmpty(text)) return emptyList() + val matcher = Patterns.WEB_URL.matcher(text) + val urls: MutableList = ArrayList() while (matcher.find()) { - urls.add(matcher.group()); + urls.add(matcher.group()) } - return urls; + return urls } // https://github.com/notslang/instagram-id-to-url-segment - public static long shortcodeToId(final String shortcode) { - long result = 0L; - for (int i = 0; i < shortcode.length() && i < 11; i++){ - final char c = shortcode.charAt(i); - final int k = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".indexOf(c); - result = result * 64 + k; + @JvmStatic + fun shortcodeToId(shortcode: String): Long { + var result = 0L + var i = 0 + while (i < shortcode.length && i < 11) { + val c = shortcode[i] + val k = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".indexOf(c) + result = result * 64 + k + i++ } - return result; + return result } -} +} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/utils/UrlEncoder.java b/app/src/main/java/awais/instagrabber/utils/UrlEncoder.java deleted file mode 100755 index 4795ad97..00000000 --- a/app/src/main/java/awais/instagrabber/utils/UrlEncoder.java +++ /dev/null @@ -1,74 +0,0 @@ -package awais.instagrabber.utils; - -import androidx.annotation.NonNull; - -import java.io.CharArrayWriter; -import java.util.BitSet; - -// same as java.net.URLEncoder -public final class UrlEncoder { - private static final BitSet dontNeedEncoding = new BitSet(256); - private static final int caseDiff = ('a' - 'A'); - - static { - int i; - for (i = 'a'; i <= 'z'; i++) dontNeedEncoding.set(i); - for (i = 'A'; i <= 'Z'; i++) dontNeedEncoding.set(i); - for (i = '0'; i <= '9'; i++) dontNeedEncoding.set(i); - dontNeedEncoding.set(' '); - dontNeedEncoding.set('-'); - dontNeedEncoding.set('_'); - dontNeedEncoding.set('.'); - dontNeedEncoding.set('*'); - } - - @NonNull - public static String encodeUrl(@NonNull final String s) { - final StringBuilder out = new StringBuilder(s.length()); - final CharArrayWriter charArrayWriter = new CharArrayWriter(); - - boolean needToChange = false; - for (int i = 0; i < s.length(); ) { - int c = s.charAt(i); - - if (dontNeedEncoding.get(c)) { - if (c == ' ') { - c = '+'; - needToChange = true; - } - - out.append((char) c); - i++; - } else { - do { - charArrayWriter.write(c); - if (c >= 0xD800 && c <= 0xDBFF && i + 1 < s.length()) { - final int d = s.charAt(i + 1); - if (d >= 0xDC00 && d <= 0xDFFF) { - charArrayWriter.write(d); - i++; - } - } - i++; - } while (i < s.length() && !dontNeedEncoding.get(c = s.charAt(i))); - - charArrayWriter.flush(); - - final byte[] ba = charArrayWriter.toString().getBytes(); - for (final byte b : ba) { - out.append('%'); - char ch = Character.forDigit((b >> 4) & 0xF, 16); - if (Character.isLetter(ch)) ch -= caseDiff; - out.append(ch); - ch = Character.forDigit(b & 0xF, 16); - if (Character.isLetter(ch)) ch -= caseDiff; - out.append(ch); - } - charArrayWriter.reset(); - needToChange = true; - } - } - - return (needToChange ? out.toString() : s); - } -} \ No newline at end of file