一、authcode的unicode版本:此版本的php实现与discuz的有区别,如需原版authcode对应的java,objc实现请见『二』
PHP
<?php
// $binary = "111001001011100010100101";
// $hex = dechex(bindec($binary));
// echo $hex;exit;
// echo bin2hex('111001001011100010100101');exit;
/**
* 将utf-8编码的字符转换成对应的unicode编码的十进制值
* https://www.cnblogs.com/lxjshuju/p/6812387.html
*/
function utf8_str_to_unicode($utf8_str) {
$unicode = 0;
$len = strlen($utf8_str);
if(1 == $len) {
return ord($utf8_str);
} elseif(2 == $len) { // 2字节的utf-8
$unicode = (ord($utf8_str[0]) & 0x1F) << 6;
$unicode |= (ord($utf8_str[1]) & 0x3F);
} elseif(3 == $len) { // 3字节的utf-8
$unicode = (ord($utf8_str[0]) & 0x0F) << 12;
$unicode |= (ord($utf8_str[1]) & 0x3F) << 6;
$unicode |= (ord($utf8_str[2]) & 0x3F);
}
return $unicode;
}
function unichr($u) {
return mb_convert_encoding('&#' . intval($u) . ';', 'UTF-8', 'HTML-ENTITIES');
}
function uniord($string, $begin_index) {
$c = mb_substr($string, $begin_index, 1);
return utf8_str_to_unicode($c);
}
function authCode($string, $auth_key = null, $operation='ENCODE') {
$auth_key = !$auth_key ? 'faL+%IUVB#c~U*CPk7MJnq0VVNs~nrE^' : $auth_key;
$key = md5($auth_key);
$key_length = strlen($key);
//base64_decode 默认是 iso-8859-1 转 UTF-8 用 utf8_decode(base64_decode($string))
$string = $operation == 'DECODE' ? utf8_decode(base64_decode($string)) : substr(md5($string.$key), 0, 8).$string;
$string_length = mb_strlen($string);
$rndkey = $box = array();
$result = '';
for($i = 0; $i <= 255; $i++) {
$rndkey[$i] = ord($key[$i % $key_length]);
$box[$i] = $i;
}
for($j = $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}
for($a = $j = $i = 0; $i < $string_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result .= unichr(uniord($string, $i) ^ ($box[($box[$a] + $box[$j]) % 256]));
}
if($operation == 'DECODE') {
if(mb_substr($result, 0, 8) == mb_substr(md5(mb_substr($result, 8).$key), 0, 8)) {
return mb_substr($result, 8);
} else {
return '';
}
} else {
//base64_encode 默认是 iso-8859-1 转 UTF-8 用 base64_encode(utf8_encode($result))
return str_replace('=', '',base64_encode(utf8_encode($result)));
}
}
$code = authCode('该函数将 data 字符串转换为 UTF-8 编码,并返回编码后的字符串。UTF-8 是一种用于将宽字符值转换为字节流的 Unicode 的标准机制。UTF-8 对于纯 ASCII 字符来说是透明的,且是自同步的(也就是说这使得程序能够得知字符从字节流的何处开始),并可被普通字符串比较函数用以比较等操作。PHP 可将 UTF-8 编码为多达四个字节的字符,如:', null, 'ENCODE');
echo $code ."\r\n\r\n";
echo authCode($code, null, 'DECODE');
JAVA版:
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
public class Authcode {
private static String CutString(String str, int startIndex, int length) {
if (startIndex >= 0) {
if (length < 0) {
length = length * -1;
if (startIndex - length < 0) {
length = startIndex;
startIndex = 0;
} else {
startIndex = startIndex - length;
}
}
if (startIndex > str.length()) {
return "";
}
} else {
if (length < 0) {
return "";
} else {
if (length + startIndex > 0) {
length = length + startIndex;
startIndex = 0;
} else {
return "";
}
}
}
if (str.length() - startIndex < length) {
length = str.length() - startIndex;
}
return str.substring(startIndex, startIndex + length);
}
public static String Encode(String string, String auth_key, String operation) {
String key = MD52(auth_key);
int key_length = key.length();
//base64_decode 默认是 iso-8859-1 转 UTF-8 用 utf8_decode(base64_decode($string))
string = CutString(MD52(string + key), 0, 8) + string;
int string_length = string.length();
ArrayList<Character> rndkey = new ArrayList<>();
ArrayList<Integer> box = new ArrayList<>();
String result = "";
for(int i = 0; i <= 256; i++) {
char b = (char)key.charAt(i % key_length);
rndkey.add(b);
box.add(i);
}
for(int j =0 , i = 0; i < 256; i++) {
j = (j + box.get(i) + rndkey.get(i)) % 256;
int tmp = box.get(i);
box.set(i, box.get(j));
box.set(j, tmp);
}
for(int a = 0, j = 0, i = 0; i < string_length; i++) {
a = (a + 1) % 256;
j = (j + box.get(a)) % 256;
int tmp = box.get(a);
box.set(a, box.get(j));
box.set(j, tmp);
char c = (char) string.charAt(i);
int tmp1 = box.get((box.get(a) + box.get(j)) % 256);
char tmp2 = (char) (c ^ tmp1);
//System.out.println(tmp2);
result += tmp2;
//System.out.println(c);
}
//System.out.println(result);System.exit(0);
//System.out.println(MD52(result));System.exit(0);
//base64_encode 默认是 iso-8859-1 转 UTF-8 用 base64_encode(utf8_encode($result))
try {
return Base64.encode(new String(result.getBytes("UTF-8"), "ISO-8859-1").getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//return str_replace('=', '',base64_encode(utf8_encode($result)));
return result;
}
private static String MD52(String MD5) {
StringBuffer sb = new StringBuffer();
String part = null;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] md5 = md.digest(MD5.getBytes());
for (int i = 0; i < md5.length; i++) {
part = Integer.toHexString(md5[i] & 0xFF);
if (part.length() == 1) {
part = "0" + part;
}
sb.append(part);
}
} catch (NoSuchAlgorithmException ex) {
}
return sb.toString();
}
public static void main(String[] args) throws Exception {
String test = "该函数将 data 字符串转换为 UTF-8 编码,并返回编码后的字符串。UTF-8 是一种用于将宽字符值转换为字节流的 Unicode 的标准机制。UTF-8 对于纯 ASCII 字符来说是透明的,且是自同步的(也就是说这使得程序能够得知字符从字节流的何处开始),并可被普通字符串比较函数用以比较等操作。PHP 可将 UTF-8 编码为多达四个字节的字符,如:";
String key = "faL+%IUVB#c~U*CPk7MJnq0VVNs~nrE^";
String afStr = Authcode.Encode(test, key, "ENCODE");
System.out.println("--------encode:" + afStr);
}
}