From bf30031971033adbe4e0bc3ad2a60e0cc6079d38 Mon Sep 17 00:00:00 2001 From: coolsnowwolf Date: Fri, 29 Sep 2017 12:38:03 +0800 Subject: [PATCH] add luci-app-kuainiao from stone --- package/lean/luci-app-kuainiao/Makefile | 17 + .../luasrc/controller/kuainiao.lua | 34 + .../luasrc/model/cbi/kuainiao.lua | 59 ++ .../luasrc/view/kuainiao/kuainiao_rsa.htm | 25 + .../luasrc/view/kuainiao/kuainiao_status.htm | 38 ++ .../luci-app-kuainiao/po/zh-cn/kuainiao.po | 4 + .../root/etc/config/kuainiao | 8 + .../root/etc/hotplug.d/iface/99-kuainiao | 15 + .../root/etc/init.d/kuainiao | 45 ++ .../root/etc/uci-defaults/luci-kuainiao | 9 + .../luci-app-kuainiao/root/usr/bin/kuainiao | 606 ++++++++++++++++++ .../root/usr/bin/luci_kuainiao_apply | 12 + .../usr/share/kuainiao/kuainiao_down_state | 1 + .../root/usr/share/kuainiao/kuainiao_up_state | 1 + .../root/www/luci-static/resources/md5.js | 1 + .../root/www/luci-static/resources/rsa.js | 1 + .../root/www/luci-static/resources/sha1.js | 202 ++++++ 17 files changed, 1078 insertions(+) create mode 100644 package/lean/luci-app-kuainiao/Makefile create mode 100644 package/lean/luci-app-kuainiao/luasrc/controller/kuainiao.lua create mode 100644 package/lean/luci-app-kuainiao/luasrc/model/cbi/kuainiao.lua create mode 100644 package/lean/luci-app-kuainiao/luasrc/view/kuainiao/kuainiao_rsa.htm create mode 100644 package/lean/luci-app-kuainiao/luasrc/view/kuainiao/kuainiao_status.htm create mode 100644 package/lean/luci-app-kuainiao/po/zh-cn/kuainiao.po create mode 100644 package/lean/luci-app-kuainiao/root/etc/config/kuainiao create mode 100755 package/lean/luci-app-kuainiao/root/etc/hotplug.d/iface/99-kuainiao create mode 100755 package/lean/luci-app-kuainiao/root/etc/init.d/kuainiao create mode 100755 package/lean/luci-app-kuainiao/root/etc/uci-defaults/luci-kuainiao create mode 100755 package/lean/luci-app-kuainiao/root/usr/bin/kuainiao create mode 100755 package/lean/luci-app-kuainiao/root/usr/bin/luci_kuainiao_apply create mode 100644 package/lean/luci-app-kuainiao/root/usr/share/kuainiao/kuainiao_down_state create mode 100644 package/lean/luci-app-kuainiao/root/usr/share/kuainiao/kuainiao_up_state create mode 100644 package/lean/luci-app-kuainiao/root/www/luci-static/resources/md5.js create mode 100644 package/lean/luci-app-kuainiao/root/www/luci-static/resources/rsa.js create mode 100644 package/lean/luci-app-kuainiao/root/www/luci-static/resources/sha1.js diff --git a/package/lean/luci-app-kuainiao/Makefile b/package/lean/luci-app-kuainiao/Makefile new file mode 100644 index 000000000..6e8319b3f --- /dev/null +++ b/package/lean/luci-app-kuainiao/Makefile @@ -0,0 +1,17 @@ +# Copyright (C) 2016 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for Kuainiao +LUCI_DEPENDS:=+kmod-ppp +openssl-util +wget +kmod-mppe +LUCI_PKGARCH:=all +PKG_VERSION:=1.0 +PKG_RELEASE:=3 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature + diff --git a/package/lean/luci-app-kuainiao/luasrc/controller/kuainiao.lua b/package/lean/luci-app-kuainiao/luasrc/controller/kuainiao.lua new file mode 100644 index 000000000..378517c42 --- /dev/null +++ b/package/lean/luci-app-kuainiao/luasrc/controller/kuainiao.lua @@ -0,0 +1,34 @@ +module("luci.controller.kuainiao", package.seeall) + +function index() + local fs = luci.fs or nixio.fs + if not fs.access("/etc/config/kuainiao") then + return + end + + local page = entry({"admin", "services", "kuainiao"}, cbi("kuainiao"), _("Kuai Niao"),201) + page.dependent = true + entry({"admin","services","kuainiao","status"},call("kuainiao_status")).leaf=true + entry({"admin","services","kuainiao","dwonstatus"},call("down_status")).leaf=true + entry({"admin","services","kuainiao","upstatus"},call("up_status")).leaf=true +end + +function kuainiao_status() +local e={} +e.running=luci.sys.exec("ps |grep -v grep |grep -w '/usr/bin/kuainiao' ") +luci.http.prepare_content("application/json") +luci.http.write_json(e) +end + +function up_status() +local e={} +e.upstatus=luci.sys.exec("cat /usr/share/kuainiao/kuainiao_up_state") +luci.http.prepare_content("application/json") +luci.http.write_json(e) +end +function down_status() +local e={} +e.dwonstatus=luci.sys.exec("cat /usr/share/kuainiao/kuainiao_down_state") +luci.http.prepare_content("application/json") +luci.http.write_json(e) +end diff --git a/package/lean/luci-app-kuainiao/luasrc/model/cbi/kuainiao.lua b/package/lean/luci-app-kuainiao/luasrc/model/cbi/kuainiao.lua new file mode 100644 index 000000000..3fec7cd00 --- /dev/null +++ b/package/lean/luci-app-kuainiao/luasrc/model/cbi/kuainiao.lua @@ -0,0 +1,59 @@ +#fork from https://github.com/zz090923610/thunder-fastNiao,thanks to zz090923610 +require("luci.sys") +require("luci.sys.zoneinfo") +require("luci.config") +local fs = require "nixio.fs" +local ut = require "luci.util" +local o=require"luci.model.network".init() +local sys = require "luci.sys" +local m,t,e +m = Map("kuainiao", translate("迅雷快鸟"),translate("迅雷快鸟是迅雷联合宽带运营商推出的一款致力于帮助用户解决宽带低、网速慢、上网体验差的专业级宽带加速软件。")) +m:section(SimpleSection).template = "kuainiao/kuainiao_status" +s = m:section(NamedSection, "base", "kuainiao", translate("首次使用请填写完帐号密码保存提交一次,之后再启用。")) +s.addremove = false +s:tab("base",translate("Basic Settings")) +s:tab("log",translate("快鸟日志")) +enabled = s:taboption("base",Flag, "enabled", translate("Enable")) +enabled.default=0 +enabled.rmempty = false +enable_down = s:taboption("base",Flag, "enable_down", translate("开启下行加速")) +enable_down.default=1 +enabled.rmempty = false +enable_down:depends("enabled",1) + +enable_up = s:taboption("base",Flag, "enable_up", translate("开启上行加速")) +enable_up.default=0 +enabled.rmempty = false +enable_up:depends("enabled",1) +local a +speed_wan=s:taboption("base",ListValue,"speed_wan",translate("指定加速的接口")) +for a,s in ipairs(o:get_networks())do +if s:name()~="loopback" and s:name()~="lan" then speed_wan:value(s:name())end +end +username = s:taboption("base",Value, "kuainiao_name", translate("迅雷快鸟帐号")) +username.datatype = "minlength(1)" +username.rmempty = false +password = s:taboption("base",Value, "kuainiao_passwd", translate("迅雷快鸟密码")) +password.password = true +password.datatype = "minlength(1)" +password.rmempty = false +kuainiao_config_pwd = s:taboption("base",Value, "kuainiao_config_pwd", translate("加密后密码(自动生成,勿修改)")) +kuainiao_config_pwd.password = true +kuainiao_config_pwd.datatype = "minlength(1)" +kuainiao_config_pwd.rmempty = true +--kuainiao_config_pwd.readonly=true +log=s:taboption("log",TextValue,"log") +log.rows=26 +log.wrap="off" +log.readonly=true +log.cfgvalue=function(t,t) +return nixio.fs.readfile("/var/log/kuainiao.log")or"" +end +log.write=function(log,log,log) +end +m:section(SimpleSection).template = "kuainiao/kuainiao_rsa" +local apply = luci.http.formvalue("cbi.apply") +if apply then + io.popen("luci_kuainiao_apply") +end +return m diff --git a/package/lean/luci-app-kuainiao/luasrc/view/kuainiao/kuainiao_rsa.htm b/package/lean/luci-app-kuainiao/luasrc/view/kuainiao/kuainiao_rsa.htm new file mode 100644 index 000000000..9d8c45871 --- /dev/null +++ b/package/lean/luci-app-kuainiao/luasrc/view/kuainiao/kuainiao_rsa.htm @@ -0,0 +1,25 @@ +<%# + Copyright (C) 2017 Jian Chang + Licensed to the public under the GNU General Public License v3. +-%> + + + + +<% include("cbi/map") %> + + diff --git a/package/lean/luci-app-kuainiao/luasrc/view/kuainiao/kuainiao_status.htm b/package/lean/luci-app-kuainiao/luasrc/view/kuainiao/kuainiao_status.htm new file mode 100644 index 000000000..93c28e579 --- /dev/null +++ b/package/lean/luci-app-kuainiao/luasrc/view/kuainiao/kuainiao_status.htm @@ -0,0 +1,38 @@ +<%# + Copyright 2017 Lede by stones +-%> + +<% include("cbi/map") %> + + +
+ <%:快鸟运行状态:%><%:Collecting data...%> + + + <%:下行提速状态:%><%:Collecting data...%> + + <%:上行提速状态:%><%:Collecting data...%> +
\ No newline at end of file diff --git a/package/lean/luci-app-kuainiao/po/zh-cn/kuainiao.po b/package/lean/luci-app-kuainiao/po/zh-cn/kuainiao.po new file mode 100644 index 000000000..fc29d8849 --- /dev/null +++ b/package/lean/luci-app-kuainiao/po/zh-cn/kuainiao.po @@ -0,0 +1,4 @@ +msgid "Kuai Niao" +msgstr "迅雷快鸟" + + diff --git a/package/lean/luci-app-kuainiao/root/etc/config/kuainiao b/package/lean/luci-app-kuainiao/root/etc/config/kuainiao new file mode 100644 index 000000000..0c4db8d66 --- /dev/null +++ b/package/lean/luci-app-kuainiao/root/etc/config/kuainiao @@ -0,0 +1,8 @@ + +config kuainiao 'base' + option kuainiao_name '' + option kuainiao_passwd '' + option speed_wan 'wan' + option enabled '0' + option enable_down '1' + option enable_up '0' diff --git a/package/lean/luci-app-kuainiao/root/etc/hotplug.d/iface/99-kuainiao b/package/lean/luci-app-kuainiao/root/etc/hotplug.d/iface/99-kuainiao new file mode 100755 index 000000000..2f42f3093 --- /dev/null +++ b/package/lean/luci-app-kuainiao/root/etc/hotplug.d/iface/99-kuainiao @@ -0,0 +1,15 @@ +#!/bin/sh +. /lib/functions.sh + +enabled=`uci -q get kuainiao.base.enabled` +[ "enabled" -eq 1 ] || exit 0 +[ "$ACTION" = ifup ] && { + logger -t Thunder kuainiao has reloaded due to Device: $DEVICE Action: $ACTION ; + /etc/init.d/kuainiao stop && sleep 2; + /etc/init.d/kuainiao start; +} + +[ "$ACTION" = ifdown ] && { + logger -t Thunder KuaiNiao has stoped due to Device: $DEVICE Action: $ACTION ; + /etc/init.d/kuainiao stop; +} \ No newline at end of file diff --git a/package/lean/luci-app-kuainiao/root/etc/init.d/kuainiao b/package/lean/luci-app-kuainiao/root/etc/init.d/kuainiao new file mode 100755 index 000000000..29f7c8adb --- /dev/null +++ b/package/lean/luci-app-kuainiao/root/etc/init.d/kuainiao @@ -0,0 +1,45 @@ +#!/bin/sh /etc/rc.common + +USE_PROCD=1 +START=99 +STOP=15 +SERVICE_WRITE_PID=1 +SERVICE_DAEMONIZE=1 +LOGFILE=/var/log/kuainiao.log + +start_service() +{ + procd_open_instance + procd_set_param command /usr/bin/kuainiao + procd_set_param respawn ${respawn_threshold:-5} ${respawn_timeout:-300} ${respawn_retry:-10} + procd_close_instance +} + +stop_service(){ + clean_log + pid_kuainiao=`ps | grep -v grep | grep -w "/usr/bin/kuainiao" |awk '{print $1}' 2>/dev/null` + [ -n "$pid_kuainiao" ] && { + for pid in $pid_kuainiao + do + echo "Stop service kuainiao PID: $pid" + kill $pid 2>/dev/null + for spid in `pgrep sleep` + do + ppid=`cat /proc/$spid/status | grep -w "PPid" | awk '{print $2}'` + [ "$ppid" -eq "$pid" ] && kill $spid 2>/dev/null && echo "Stop service kuainiao SPID: $spid" + done + done + } + echo "暂无加速信息" > /usr/share/kuainiao/kuainiao_down_state + echo "暂无加速信息" > /usr/share/kuainiao/kuainiao_up_state +} + +clean_log() { + [ -f "$LOGFILE" ] && { + logsnum=$(cat $LOGFILE | grep -c .) + if [ $logsnum -gt 300 ];then + rm -f $LOGFILE >/dev/null 2>&1 & + echo "$(date): 日志文件过长,清空处理!" >> $LOGFILE + fi + } +} diff --git a/package/lean/luci-app-kuainiao/root/etc/uci-defaults/luci-kuainiao b/package/lean/luci-app-kuainiao/root/etc/uci-defaults/luci-kuainiao new file mode 100755 index 000000000..b8b12cac8 --- /dev/null +++ b/package/lean/luci-app-kuainiao/root/etc/uci-defaults/luci-kuainiao @@ -0,0 +1,9 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@kuainiao[-1] + add ucitrack kuainiao + set ucitrack.@kuainiao[-1].init=kuainiao + commit ucitrack +EOF +exit 0 \ No newline at end of file diff --git a/package/lean/luci-app-kuainiao/root/usr/bin/kuainiao b/package/lean/luci-app-kuainiao/root/usr/bin/kuainiao new file mode 100755 index 000000000..f5e520540 --- /dev/null +++ b/package/lean/luci-app-kuainiao/root/usr/bin/kuainiao @@ -0,0 +1,606 @@ +#!/bin/sh +#2017/05/01 by kenney +#2017/07/19 update for lede by stones +. /lib/functions.sh + +LOGFILE=/var/log/kuainiao.log +down_state_file=/usr/share/kuainiao/kuainiao_down_state +up_state_file=/usr/share/kuainiao/kuainiao_up_state +version="0.4" +app_version="2.0.3.4" +protocolVersion=108 +sdkVersion=17550 +logmore=0 #打印更详细日志排查 + + +logmore(){ + data=$1 + [ "$logmore" -eq 1 ] && { + echo $(date): $data >> $LOGFILE + } +} + +log_down(){ + kuainiao_down_state=$1 + status=$2 + if [ "$status" -eq 1 ]; then + echo "$kuainiao_down_state" > $down_state_file + else + echo "$kuainiao_down_state" > $down_state_file + fi +} + +log_up(){ + kuainiao_up_state=$1 + status=$2 + if [ "$status" -eq 1 ]; then + echo "$kuainiao_up_state" > $up_state_file + else + echo "$kuainiao_up_state" > $up_state_file + fi +} + +#WAN接口IP判断 +get_bind_address(){ + ifname=$(uci -P /var/state get network.$kuainiao_config_wan.ifname 2>/dev/null) + [ $? -eq 1 ] && echo $(date): "获取网络 $kuainiao_config_wan 信息出错" >>$LOGFILE && echo >>$LOGFILE && return + logmore "ifname is $ifname" + ##wan_selected 所选接口IP + wan_selected=$(ifconfig $ifname 2>/dev/null | grep 'inet addr' | awk '{print $2}' | cut -d: -f2 2>/dev/null) + [ -z "$wan_selected" ] && echo $(date): "获取网络 $kuainiao_config_wan 接口 $ifname 信息出错" >>$LOGFILE && echo >>$LOGFILE && return + if [ "$wan_selected" != "0.0.0.0" ]; then + bind_address=$wan_selected + else + bind_address="" + fi +} + +#定义请求函数 +#bind_address='113.248.3.11' +get_http_req(){ + if [ -n "$bind_address" ]; then + HTTP_REQ="wget --bind-address=$bind_address --no-check-certificate -O - " + POST_ARG="--post-data=" + else + HTTP_REQ="wget --no-check-certificate -O - " + POST_ARG="--post-data=" + fi + kuainiao_HTTP_REQ=$HTTP_REQ + kuainiao_POST_ARG=$POST_ARG +} + +#数据mock + +generate_pwd_rsa_hex() +{ + # calculate passwd_md5 + logmore "Generating passwd md5" + passwd_md5=`echo -n "$kuainiao_config_pwd" | md5sum | tr -d " -"` + + if [ `echo -n "$passwd_md5" | wc -c` -ne 32 ]; then + logmore "md5sum should be 32 chars, exit." + exit 1 + fi + + logmore "Generating PWD RSA HEX" + #first, encoding passwd using rsa + a=`echo "$passwd_md5" | openssl rsautl -raw -pubin -inkey /etc/thunder.key -hexdump | tr [a-z] [A-Z]` + a=`echo $a | grep -o '00[0-9]0 \- \([A-Z0-9]\{2\}[- ]\)\{16\}' | sed 's/00[0-9]0 - //g' | tr -d " \-\n"` + echo -n "$a" + +} + +#pwd='702CFAF5824E4306516F488DEAFC2D24F76C82FA53BA3396F5615FDD32E4430E45B254E136056ED5F3C5B404A08E2178B51330999A4EC3C2D2989D554D7863BDE8F058F44808E6B65F4D071B5D5C7210210DA9ED8D729312CECA39E0F4516143E33C089F616ABE93E14D3224BEB311D3D6EF65A6CE265D3E4ABA285523F14320' + +get_device_sign(){ + ifname=$(uci get network.$kuainiao_config_wan.ifname 2>/dev/null) + wan_mac=$(ifconfig $ifname | grep 'HWaddr' | awk '{print $5}') + fake_device_id=$(echo -n "$wan_mac" | md5sum | cut -d ' ' -f1) + fake_device_id_tmp1=$(echo -n "$fake_device_id"com.xunlei.vip.swjsq68700d1872b772946a6940e4b51827e8af"" | openssl sha1 -hmac | awk '{print $2}') + devicesign="div100."${fake_device_id}$(echo -n "$fake_device_id_tmp1" | md5sum | cut -d ' ' -f1) +} + + +#verifyCode=$kuainiao_config_verifyCode +#verifyKey=$kuainiao_verifyKey + +#获取用户真实MAC地址 +get_mac_addr(){ + if [ -n "$bind_address" ]; then + ifname=$(uci get network.$kuainiao_config_wan.ifname 2>/dev/null) + peerid=$(ifconfig $ifname | grep 'HWaddr' | awk '{print $5}' | awk 'gsub(/:/, "")')004V + fi + #peerid='000C29212478004V' +} + + +#获取迅雷用户uid +get_xunlei_uid(){ + get_http_req + logmore "HTTP_REQ is $HTTP_REQ" + logmore "POST_ARG is $POST_ARG" + uname=$kuainiao_config_uname + #get_mac_addr + logmore "peerid is $peerid" + [ -z "$peerid" ] && exit 0 + #pwd=$generate_pwd_rsa_hex + pwd=$kuainiao_config_pwd + get_device_sign + logmore "devicesign is $devicesign" + ret=`$HTTP_REQ --header "User-Agent:android-async-http/xl-acc-sdk/version-1.6.1.177600" https://login.mobile.reg2t.sandai.net:443/ $POST_ARG"{\"userName\":\""$uname"\",\"businessType\":68,\"clientVersion\":\"$app_version\",\"appName\":\"ANDROID-com.xunlei.vip.swjsq\",\"isCompressed\":0,\"sequenceNo\":1000001,\"sessionID\":\"\",\"loginType\":0,\"rsaKey\":{\"e\":\"010001\",\"n\":\"AC69F5CCC8BDE47CD3D371603748378C9CFAD2938A6B021E0E191013975AD683F5CBF9ADE8BD7D46B4D2EC2D78AF146F1DD2D50DC51446BB8880B8CE88D476694DFC60594393BEEFAA16F5DBCEBE22F89D640F5336E42F587DC4AFEDEFEAC36CF007009CCCE5C1ACB4FF06FBA69802A8085C2C54BADD0597FC83E6870F1E36FD\"},\"cmdID\":1,\"verifyCode\":\"$verifyCode\",\"peerID\":\""$peerid"\",\"protocolVersion\":$protocolVersion,\"platformVersion\":1,\"passWord\":\""$pwd"\",\"extensionList\":\"\",\"verifyKey\":\"$verifyKey\",\"sdkVersion\":$sdkVersion,\"devicesign\":\""$devicesign"\"}"` + #判断是否登陆成功 + #echo $ret >>test.txt + logmore "........................" + logmore "ret is $ret" + logmore "........................" + session=`echo $ret|awk -F '"sessionID":' '{print $2}'|awk -F '[,}]' '{print $1}'|grep -oE "[A-F,0-9]{32}"` + logmore "session is $session" + #vcode=`echo $ret|awk -F '"errorDescUrl":' '{print $2}'|awk -F '}' '{print $1}'` + #vcode=`echo $vcode|sed 's/\\//g'` + errcode=`echo $ret|awk -F '"errorCode":' '{print $2}'|awk -F '[,}]' '{print $1}'` + logmore "errcode is $errcode" + if [ -z "$session" ]; then + if [ $errcode == 6 ];then + #kuainiao_vcodeimg_url="$vcode" + #kuainiao_verifyKey='F9F6FBE928911784D809EBF046ABE0A6A467583F3944507099EA54BC9B5DA7BD' + kuainiao_last_act="您的账号不安全,需要输入验证码! $(date "+%Y-%m-%d %H:%M:%S")" + + elif [ $errcode == 12 ];then + #kuainiao_vcodeimg_url="" + #kuainiao_verifyKey='' + kuainiao_last_act="登陆协议无效,请更新!$(date "+%Y-%m-%d %H:%M:%S")" + + elif [ $errcode == 3 ];then + #kuainiao_vcodeimg_url="" + #kuainiao_verifyKey='' + kuainiao_last_act="用户名密码错误,请检查!$(date "+%Y-%m-%d %H:%M:%S")" + + else + #kuainiao_vcodeimg_url="" + #kuainiao_verifyKey='' + kuainiao_last_act="迅雷账号登陆失败,请检查输入的用户名密码! $(date "+%Y-%m-%d %H:%M:%S")" + + fi + #echo "迅雷账号登陆失败,请检查输入的用户名密码!" + log_down "$kuainiao_last_act" 0 + + else + uid=`echo $ret|awk -F '"userID":' '{print $2}'|awk -F '[,}]' '{print $1}'` + kuainiao_config_uid=$uid + kuainiao_config_session=$session + kuainiao_last_act="迅雷快鸟已登陆成功!" + log_down "$kuainiao_last_act" 1 + fi + echo $(date): "$kuainiao_last_act" >> $LOGFILE +} + +#获取加速API +get_kuainiao_api(){ + portal=`$HTTP_REQ http://api.portal.swjsq.vip.xunlei.com:81/v2/queryportal` + portal_ip=`echo $portal|grep -oE '([0-9]{1,3}[\.]){3}[0-9]{1,3}'` + portal_port_temp=`echo $portal|grep -oE "port...[0-9]{1,5}"` + portal_port=`echo $portal_port_temp|grep -oE '[0-9]{1,5}'` + + logmore "portal is $portal" >> $LOGFILE + logmore "portal_ip is $portal_ip" >> $LOGFILE + logmore "portal_port_temp is $portal_port_temp" >> $LOGFILE + logmore "portal_port is $portal_port" >> $LOGFILE + + if [ -z "$portal_ip" ]; then + kuainiao_down_state="迅雷快鸟下行API获取失败,请检查网络环境,或稍后再试!" + echo $(date): "$kuainiao_down_state" >> $LOGFILE + log_down "$kuainiao_down_state" 0 + else + api_url="http://$portal_ip:$portal_port/v2" + kuainiao_config_api=$api_url + fi +} + +#获取上行加速API +get_kuainiao_upapi(){ + upportal=`$HTTP_REQ http://api.upportal.swjsq.vip.xunlei.com/v2/queryportal` + upportal_ip=`echo $upportal|grep -oE '([0-9]{1,3}[\.]){3}[0-9]{1,3}'` + upportal_port_temp=`echo $upportal|grep -oE "port...[0-9]{1,5}"` + upportal_port=`echo $upportal_port_temp|grep -oE '[0-9]{1,5}'` + + logmore "upportal is $upportal" + logmore "upportal_ip is $upportal_ip" + logmore "upportal_port_temp is $upportal_port_temp" + logmore "upportal_port is $upportal_port" + + if [ -z "$upportal_ip" ]; then + kuainiao_up_state="迅雷快鸟上行API获取失败,请检查网络环境,或稍后再试!" + #echo "迅雷快鸟服务API获取失败,请检查网络环境,或稍后再试!" + echo $(date): "$kuainiao_up_state" >> $LOGFILE + log_up "$kuainiao_up_state" 0 + else + upapi_url="http://$upportal_ip:$upportal_port/v2" + kuainiao_config_upapi=$upapi_url + fi + logmore "$(date): upapi_url is $upapi_url" +} + + +#检测快鸟加速信息 +get_bandwidth(){ + + logmore "api_url is $api_url" + logmore "peerid is $peerid" + if [ -n "$api_url" ]; then + [ -n "$portal_port_temp" ] && [ -n "$portal_port" ] && bandwidth + band=$width + logmore "band is $band" + can_upgrade=`echo $band|awk -F '"can_upgrade":' '{print $2}'|awk -F '[,}]' '{print $1}'` + logmore "can_upgrade is $can_upgrade" + kuainiao_can_upgrade=$can_upgrade + logmore "kuainiao_can_upgrade is $kuainiao_can_upgrade" + dial_account=`echo $band|awk -F '"dial_account":"' '{print $2}'|awk -F '[,}"]' '{print $1}'` + kuainiao_dial_account=$dial_account + logmore "kuainiao_dial_account is $kuainiao_dial_account" + #判断是否满足加速条件 + if [ "$can_upgrade" -eq 1 ]; then + #echo "迅雷快鸟可以加速~~~愉快的开始加速吧~~" + #获取加速详细信息 + old_downstream=`echo $band|awk -F '"bandwidth":' '{print $2}'|awk -F '"downstream":' '{print $2}'|awk -F '[,}]' '{print $1}'` + max_downstream=`echo $band|awk -F '"max_bandwidth":' '{print $2}'|awk -F '"downstream":' '{print $2}'|awk -F '[,}]' '{print $1}'` + down_state="下行可以加速" + kuainiao_old_downstream=$(expr $old_downstream / 1024) + kuainiao_max_downstream=$(expr $max_downstream / 1024) + logmore "kuainiao_old_downstream is $kuainiao_old_downstream" + logmore "kuainiao_max_downstream is $kuainiao_max_downstream" + else + down_state="下行不满足加速条件" + #echo "T_T 不能加速啊,不满足加速条件哦~~" + log_down "$down_state" 0 + fi + echo $(date): "$down_state" >> $LOGFILE + # kuainiao_down_state=$down_state + + fi +} + +#检测快鸟上行加速信息 +get_upbandwidth(){ + logmore "upapi_url is $upapi_url" + if [ -n "$upapi_url" ]; then + [ -n "$upportal_port_temp" ] && [ -n "$upportal_port" ] && upbandwidth + band=$upwidth + logmore "upwidth is $upwidth" + can_upgrade=`echo $band|awk -F '"can_upgrade":' '{print $2}'|awk -F '[,}]' '{print $1}'` + kuainiao_can_upupgrade=$can_upgrade + updial_account=`echo $band|awk -F '"dial_account":"' '{print $2}'|awk -F '[,}"]' '{print $1}'` + kuainiao_dial_upaccount=$updial_account + logmore "can_upgrade is $can_upgrade" + logmore "kuainiao_can_upupgrade is $kuainiao_can_upupgrade" + logmore "updial_account is $updial_account" + logmore "kuainiao_dial_upaccount is $kuainiao_dial_upaccount" + #判断是否满足加速条件 + if [ "$can_upgrade" -eq 1 ]; then + #echo "迅雷快鸟可以加速~~~愉快的开始加速吧~~" + #获取加速详细信息 + old_upstream=`echo $band|awk -F '"bandwidth":' '{print $2}'|awk -F '"upstream":' '{print $2}'|awk -F '[,}]' '{print $1}'` + max_upstream=`echo $band|awk -F '"max_bandwidth":' '{print $2}'|awk -F '"upstream":' '{print $2}'|awk -F '[,}]' '{print $1}'` + up_state="上行可以加速" + kuainiao_old_upstream=$(expr $old_upstream / 1024) + kuainiao_max_upstream=$(expr $max_upstream / 1024) + logmore "kuainiao_old_upstream is $kuainiao_old_upstream" + logmore "kuainiao_max_upstream is $kuainiao_max_upstream" + else + up_state="上行不满足加速条件" + log_up "$up_state" 0 + fi + echo "$(date): $up_state" >> $LOGFILE + kuainiao_up_state=$up_state + + fi +} + + +#检测试用加速信息 +query_try_info(){ + info=`$HTTP_REQ "$api_url/query_try_info?peerid=$peerid&userid=$uid&user_type=1&sessionid=$session"` + echo $info +} +##{"errno":0,"message":"","number_of_try":0,"richmessage":"","sequence":0,"timestamp":1455936922,"try_duration":10} + +query_try_upinfo(){ + info=`$HTTP_REQ "$upapi_url/query_try_info?peerid=$peerid&userid=$uid&client_type=android-uplink-2.3.3.9&client_version=andrioduplink-2.3.3.9&os=android-7.0.24DUK-AL20&sessionid=$session"` + echo $info +} +##{"errno":0,"exp_day_len":0,"is_exp_day":0,"message":"","number_of_try":1,"richmessage":"","sequence":268435461,"timestamp":1493469390,"try_duration":10} + +get_upgrade_down(){ + _ts=`date +%s`000 + ret=`$HTTP_REQ "$api_url/upgrade?peerid=$peerid&userid=$uid&user_type=1&sessionid=$kuainiao_config_session&dial_account=$dial_account&client_type=android-swjsq-$app_version&client_version=androidswjsq-$app_version&os=android-5.0.1.24SmallRice&time_and=$_ts"` + errcode=`echo $ret|awk -F '"errno":' '{print $2}'|awk -F '[,}"]' '{print $1}'` + if [ "$errcode" == "0" ]; then + down_state="$down_state (您的下行带宽已从$kuainiao_old_downstream M提升到$kuainiao_max_downstream M)" + log_down "$down_state" 1 + else + down_state="$down_state 下行带宽提升失败,请检查宽带账号是否绑定正确" + log_down "$down_state" 0 + fi + echo $(date): "$down_state" >> $LOGFILE + # kuainiao_down_state=$down_state +} + +get_upgrade_up(){ + _ts=`date +%s`000 + up_ret=`$HTTP_REQ --header "User-Agent:android-async-http/xl-acc-sdk/version-1.0.0.1" "$upapi_url/upgrade?peerid=$peerid&userid=$uid&client_type=android-uplink-2.3.3.9&client_version=andrioduplink-2.3.3.9&os=android-7.0.24DUK-AL20&sessionid=$session&user_type=1&dial_account=$updial_account"` + errcode=`echo $up_ret|awk -F '"errno":' '{print $2}'|awk -F '[,}"]' '{print $1}'` + if [ "$errcode" == "0" ] || [ "$errcode" == "812" ];then + up_state="$up_state (您的上行带宽已从$kuainiao_old_upstream M提升到$kuainiao_max_upstream M)" + log_up "$up_state" 1 + else + up_state="$up_state 上行带宽提升失败,请检查宽带账号是否绑定正确" + log_up "$up_state" 0 + fi + echo $(date): "$up_state" >> $LOGFILE + # kuainiao_up_state=$up_state + # echo "$kuainiao_up_state" > $up_state_file +} + +#迅雷快鸟上行加速心跳包 +keepalive_up(){ + _ts=`date +%s`000 + up_ret=`$HTTP_REQ --header "User-Agent:android-async-http/xl-acc-sdk/version-1.0.0.1" "$upapi_url/keepalive?peerid=$peerid&userid=$uid&client_type=android-uplink-2.3.3.9&client_version=andrioduplink-2.3.3.9&os=android-7.0.24DUK-AL20&sessionid=$session&user_type=1&dial_account=$kuainiao_dial_upaccount"` + errcode=`echo $up_ret|awk -F '"errno":' '{print $2}'|awk -F '[,}"]' '{print $1}'` + if [ "$errcode" != "0" ];then + #kuainiao_run_upid=0 + kuainiao_up_state="迅雷上行提速失效!$(date '+%Y-%m-%d %H:%M:%S')" + kuainiao_run_upstatus=0 + log_up "$kuainiao_up_state" 0 + else + #kuainiao_run_upid=$(expr $kuainiao_run_upid + 1) + kuainiao_up_state="您的上行带宽已从${kuainiao_old_upstream}M提升到${kuainiao_max_upstream}M $(date '+%Y-%m-%d %H:%M:%S')" + kuainiao_run_upstatus=1 + log_up "$kuainiao_up_state" 1 + fi +} + + +#检测提速带宽 +bandwidth(){ + [ "$logmore" -eq 1 ] && { + echo $(date): "bandwidth start" >> $LOGFILE + echo $(date): "peerid is $peerid" >> $LOGFILE + echo $(date): "uid is $uid" >> $LOGFILE + echo $(date): "session is $session" >> $LOGFILE + } + _ts=`date +%s`000 + width=`$HTTP_REQ "$api_url/bandwidth?peerid=$peerid&userid=$uid&user_type=1&sessionid=$session&dial_account=$dial_account&client_type=android-swjsq-$app_version&client_version=androidswjsq-$app_version&os=android-5.0.1.24SmallRice&time_and=$_ts"` + #echo $width +} +##{"bandwidth":{"downstream":51200,"upstream":0},"can_upgrade":1,"dial_account":"100001318645","errno":0,"max_bandwidth":{"downstream":102400,"upstream":0},"message":"","province":"bei_jing","province_name":"北京","richmessage":"","sequence":0,"sp":"cnc","sp_name":"联通","timestamp":1455936922} + +upbandwidth(){ + _ts=`date +%s`000 + upwidth=`$HTTP_REQ "$upapi_url/bandwidth?peerid=$peerid&userid=$uid&user_type=1&sessionid=$session&dial_account=$dial_account&client_type=android-swjsq-$app_version&client_version=androidswjsq-$app_version&os=android-5.0.1.24SmallRice&time_and=$_ts"` + #echo $upwidth +} + + +#迅雷快鸟下行加速心跳包 +keepalive_down(){ + _ts=`date +%s`000 + ret=`$HTTP_REQ "$api_url/keepalive?peerid=$peerid&userid=$uid&user_type=1&sessionid=$session&dial_account=$dial_account&client_type=android-swjsq-$app_version&client_version=androidswjsq-$app_version&os=android-5.0.1.24SmallRice&time_and=$_ts"` + errcode=`echo $ret|awk -F '"errno":' '{print $2}'|awk -F '[,}"]' '{print $1}'` + if [ "$errcode" != "0" ];then + #kuainiao_run_upid=0 + kuainiao_down_state="迅雷下行提速失效!"$(date "+%Y-%m-%d %H:%M:%S") + log_down "$kuainiao_down_state" 0 + kuainiao_run_status=0 + else + #kuainiao_run_upid=$(expr $kuainiao_run_upid + 1) + kuainiao_down_state="您的下行带宽已从${kuainiao_old_downstream}M提升到${kuainiao_max_downstream}M $(date '+%Y-%m-%d %H:%M:%S')" + log_down "$kuainiao_down_state" 1 + kuainiao_run_status=1 + + fi + echo $(date): "$kuainiao_down_state" >> $LOGFILE +} + +sigterm(){ + + [ "$kuainiao_can_upgrade" -eq 1 ] && kuainiao_recover + [ "$kuainiao_can_upupgrade" -eq 1 ] && kuainiao_uprecover + logmore "trap sigterm exit" + exit 0 + +} + +#快鸟加速注销 +kuainiao_recover(){ + _ts=`date +%s`000 + recover=`$HTTP_REQ "$api_url/recover?peerid=$peerid&userid=$uid&user_type=1&sessionid=$session&dial_account=$dial_account&client_type=android-swjsq-$app_version&client_version=androidswjsq-$app_version&os=android-5.0.1.24SmallRice&time_and=$_ts"` + #echo $recover + echo $(date): "快鸟下行带宽加速已注销" >> $LOGFILE +} + +kuainiao_uprecover(){ + _ts=`date +%s`000 + recover=`$HTTP_REQ "$upapi_url/recover?peerid=$peerid&userid=$uid&client_type=android-uplink-2.3.3.9&client_version=andrioduplink-2.3.3.9&os=android-7.0.24DUK-AL20&sessionid=$session&user_type=1&dial_account=$updial_account"` + #echo $recover + echo $(date): "快鸟上行带宽加速已注销" >> $LOGFILE +} + +#执行初始化 +kuainiao_init(){ + local kuainiao_last_act="" + local kuainiao_can_upgrade=0 + local kuainiao_can_upupgrade=0 + local kuainiao_down_state="" + local kuainiao_up_state="" +} + +##主逻辑 +trap 'sigterm' TERM +trap 'sigterm' INT + +kuainiao_init +config_load kuainiao +config_get_bool enabled base enabled 0 +config_get_bool kuainiao_downenable base enable_down 0 +config_get_bool kuainiao_upenable base enable_up 0 +config_get kuainiao_config_wan base speed_wan +config_get kuainiao_config_uname base kuainiao_name +config_get kuainiao_config_pwd base kuainiao_config_pwd + +[ "$enabled" -eq 0 ] || [ -z "$kuainiao_config_pwd" ] && exit 0 +[ "$kuainiao_downenable" -eq 0 ] && [ "$kuainiao_upenable" -eq 0 ] && exit 0 +[ -z "$kuainiao_config_uname" ] && exit 0 + +logmore "enabled is $enabled" +logmore "kuainiao_downenable is $kuainiao_downenable" +logmore "kuainiao_upenable is $kuainiao_upenable" +logmore "kuainiao_config_wan is $kuainiao_config_wan" +logmore "kuainiao_config_uname is $kuainiao_config_uname" +logmore "kuainiao_config_pwd is $kuainiao_config_pwd" + +if [ "$kuainiao_downenable" -eq 1 ] || [ "$kuainiao_upenable" -eq 1 ]; then + + logmore "启动延时 7s" + sleep 7s + + #登陆迅雷获取uid + logmore "get_bind_address start" + get_bind_address + logmore "bind_address is $bind_address" + logmore "get_mac_addr start" + get_mac_addr + logmore "peerid is $peerid" + logmore "get_xunlei_uid start" + get_xunlei_uid + logmore "get_xunlei_uid is done" + logmore "id is $uid" + #判断是否登陆成功 + if [ -n "$uid" ]; then + if [ "$kuainiao_downenable" -eq 1 ]; then + logmore "get_kuainiao_api is started......." + get_kuainiao_api + logmore "get_bandwidth is started......." + get_bandwidth + kuainiao_config_downstream=$(expr $old_downstream / 1024) + kuainiao_config_max_downstream=$(expr $max_downstream / 1024) + logmore "kuainiao_config_downstream is $kuainiao_config_downstream" + logmore "kuainiao_config_max_downstream is $kuainiao_config_max_downstream" + logmore "kuainiao_can_upgrade is $kuainiao_can_upgrade" + + if [ "$kuainiao_can_upgrade" -eq 1 ]; then + logmore "get_upgrade_down is started......." + get_upgrade_down + logmore "get_upgrade_down is done......." + sleep 1s + #keepalive_down + fi + fi + if [ "$kuainiao_upenable" -eq 1 ]; then + logmore "get_kuainiao_upapi start" + get_kuainiao_upapi + logmore "get_upbandwidth start" + get_upbandwidth + kuainiao_config_upstream=$(expr $old_upstream / 1024) + kuainiao_config_max_upstream=$(expr $max_upstream / 1024) + logmore "kuainiao_config_upstream is $kuainiao_config_upstream" + logmore "kuainiao_config_max_upstream is $kuainiao_config_max_upstream" + logmore "kuainiao_can_upupgrade is $kuainiao_can_upupgrade" + + if [ "$kuainiao_can_upupgrade" -eq 1 ]; then + logmore "get_upgrade_up start" + get_upgrade_up + sleep 1s + #keepalive_up + fi + fi + fi +fi + +# [ -z "$kuainiao_can_upgrade" ] && [ -z "$kuainiao_can_upupgrade" ] && { + # logmore "exit kuainiao...." + # sleep 7s + # echo "暂无加速信息" > $down_state_file + # echo "暂无加速信息" > $up_state_file + # exit 0 + +# } +while true; +do + sleep 295s + if [ "$kuainiao_downenable" -eq 1 ] && [ "$kuainiao_can_upgrade" -eq 1 ];then + keepalive_down + [ "$kuainiao_run_status" -eq 0 ] && restart_kuainiao + fi + if [ "$kuainiao_upenable" -eq 1 ] && [ "$kuainiao_can_upupgrade" -eq 1 ];then + keepalive_up + [ "$kuainiao_run_upstatus" -eq 0 ] && restart_kuainiao + fi +done + + +restart_kuainiao(){ + kuainiao_init + config_load kuainiao + config_get_bool enabled base enabled 0 + config_get_bool kuainiao_downenable base enable_down 0 + config_get_bool kuainiao_upenable base enable_up 0 + config_get kuainiao_config_wan base speed_wan + config_get kuainiao_config_uname base kuainiao_name + config_get kuainiao_config_pwd base kuainiao_config_pwd + + if [ "$kuainiao_downenable" -eq 1 ] || [ "$kuainiao_upenable" -eq 1 ]; then + logmore "启动延时 7s" + sleep 7s + + #登陆迅雷获取uid + logmore "get_bind_address start" + get_bind_address + logmore "bind_address is $bind_address" + logmore "get_mac_addr start" + get_mac_addr + logmore "peerid is $peerid" + logmore "get_xunlei_uid start" + get_xunlei_uid + logmore "get_xunlei_uid is done" + logmore "id is $uid" + #判断是否登陆成功 + if [ -n "$uid" ]; then + if [ "$kuainiao_downenable" -eq 1 ]; then + logmore "get_kuainiao_api is started......." + get_kuainiao_api + logmore "get_bandwidth is started......." + get_bandwidth + kuainiao_config_downstream=$(expr $old_downstream / 1024) + kuainiao_config_max_downstream=$(expr $max_downstream / 1024) + if [ "$kuainiao_can_upgrade" -eq 1 ]; then + [ "$logmore" -eq 1 ] && logmore "get_upgrade_down is started......." + get_upgrade_down + logmore "get_upgrade_down is done......." + sleep 1s + #keepalive_down + fi + fi + if [ "$kuainiao_upenable" -eq 1 ]; then + logmore "get_kuainiao_upapi start" + get_kuainiao_upapi + logmore "get_upbandwidth start" + get_upbandwidth + kuainiao_config_upstream=$(expr $old_upstream / 1024) + kuainiao_config_max_upstream=$(expr $max_upstream / 1024) + if [ "$kuainiao_can_upupgrade" -eq 1 ]; then + logmore "get_upgrade_up start" + get_upgrade_up + sleep 1s + #keepalive_up + fi + fi + fi + #add_kuainiao_cru + fi + [ -z "$kuainiao_can_upgrade" ] && [ -z "$kuainiao_can_upupgrade" ] && { + logmore "exit kuainiao...." + sleep 7s + echo "暂无加速信息" > $down_state_file + echo "暂无加速信息" > $up_state_file + exit 0 + } +} diff --git a/package/lean/luci-app-kuainiao/root/usr/bin/luci_kuainiao_apply b/package/lean/luci-app-kuainiao/root/usr/bin/luci_kuainiao_apply new file mode 100755 index 000000000..ce48ef893 --- /dev/null +++ b/package/lean/luci-app-kuainiao/root/usr/bin/luci_kuainiao_apply @@ -0,0 +1,12 @@ +#!/bin/sh + +enabled=`uci get kuainiao.base.enabled` + +if [ "$enabled" -eq 0 ]; then + /etc/init.d/kuainiao stop + /etc/init.d/kuainiao disable +else + /etc/init.d/kuainiao stop + /etc/init.d/kuainiao start + /etc/init.d/kuainiao enable +fi \ No newline at end of file diff --git a/package/lean/luci-app-kuainiao/root/usr/share/kuainiao/kuainiao_down_state b/package/lean/luci-app-kuainiao/root/usr/share/kuainiao/kuainiao_down_state new file mode 100644 index 000000000..f01ccd0f0 --- /dev/null +++ b/package/lean/luci-app-kuainiao/root/usr/share/kuainiao/kuainiao_down_state @@ -0,0 +1 @@ +暂无加速信息 \ No newline at end of file diff --git a/package/lean/luci-app-kuainiao/root/usr/share/kuainiao/kuainiao_up_state b/package/lean/luci-app-kuainiao/root/usr/share/kuainiao/kuainiao_up_state new file mode 100644 index 000000000..f01ccd0f0 --- /dev/null +++ b/package/lean/luci-app-kuainiao/root/usr/share/kuainiao/kuainiao_up_state @@ -0,0 +1 @@ +暂无加速信息 \ No newline at end of file diff --git a/package/lean/luci-app-kuainiao/root/www/luci-static/resources/md5.js b/package/lean/luci-app-kuainiao/root/www/luci-static/resources/md5.js new file mode 100644 index 000000000..c1d09a94d --- /dev/null +++ b/package/lean/luci-app-kuainiao/root/www/luci-static/resources/md5.js @@ -0,0 +1 @@ +var md5; md5 || (md5 = function(){function i(a,b){a[b>>5]|=128<>>9<<4)+14]=b;for(var c=1732584193,d=-271733879,e=-1732584194,f=271733878,g=0;a.length>g;g+=16){var h=c,i=d,j=e,o=f;c=k(c,d,e,f,a[g+0],7,-680876936),f=k(f,c,d,e,a[g+1],12,-389564586),e=k(e,f,c,d,a[g+2],17,606105819),d=k(d,e,f,c,a[g+3],22,-1044525330),c=k(c,d,e,f,a[g+4],7,-176418897),f=k(f,c,d,e,a[g+5],12,1200080426),e=k(e,f,c,d,a[g+6],17,-1473231341),d=k(d,e,f,c,a[g+7],22,-45705983),c=k(c,d,e,f,a[g+8],7,1770035416),f=k(f,c,d,e,a[g+9],12,-1958414417),e=k(e,f,c,d,a[g+10],17,-42063),d=k(d,e,f,c,a[g+11],22,-1990404162),c=k(c,d,e,f,a[g+12],7,1804603682),f=k(f,c,d,e,a[g+13],12,-40341101),e=k(e,f,c,d,a[g+14],17,-1502002290),d=k(d,e,f,c,a[g+15],22,1236535329),c=l(c,d,e,f,a[g+1],5,-165796510),f=l(f,c,d,e,a[g+6],9,-1069501632),e=l(e,f,c,d,a[g+11],14,643717713),d=l(d,e,f,c,a[g+0],20,-373897302),c=l(c,d,e,f,a[g+5],5,-701558691),f=l(f,c,d,e,a[g+10],9,38016083),e=l(e,f,c,d,a[g+15],14,-660478335),d=l(d,e,f,c,a[g+4],20,-405537848),c=l(c,d,e,f,a[g+9],5,568446438),f=l(f,c,d,e,a[g+14],9,-1019803690),e=l(e,f,c,d,a[g+3],14,-187363961),d=l(d,e,f,c,a[g+8],20,1163531501),c=l(c,d,e,f,a[g+13],5,-1444681467),f=l(f,c,d,e,a[g+2],9,-51403784),e=l(e,f,c,d,a[g+7],14,1735328473),d=l(d,e,f,c,a[g+12],20,-1926607734),c=m(c,d,e,f,a[g+5],4,-378558),f=m(f,c,d,e,a[g+8],11,-2022574463),e=m(e,f,c,d,a[g+11],16,1839030562),d=m(d,e,f,c,a[g+14],23,-35309556),c=m(c,d,e,f,a[g+1],4,-1530992060),f=m(f,c,d,e,a[g+4],11,1272893353),e=m(e,f,c,d,a[g+7],16,-155497632),d=m(d,e,f,c,a[g+10],23,-1094730640),c=m(c,d,e,f,a[g+13],4,681279174),f=m(f,c,d,e,a[g+0],11,-358537222),e=m(e,f,c,d,a[g+3],16,-722521979),d=m(d,e,f,c,a[g+6],23,76029189),c=m(c,d,e,f,a[g+9],4,-640364487),f=m(f,c,d,e,a[g+12],11,-421815835),e=m(e,f,c,d,a[g+15],16,530742520),d=m(d,e,f,c,a[g+2],23,-995338651),c=n(c,d,e,f,a[g+0],6,-198630844),f=n(f,c,d,e,a[g+7],10,1126891415),e=n(e,f,c,d,a[g+14],15,-1416354905),d=n(d,e,f,c,a[g+5],21,-57434055),c=n(c,d,e,f,a[g+12],6,1700485571),f=n(f,c,d,e,a[g+3],10,-1894986606),e=n(e,f,c,d,a[g+10],15,-1051523),d=n(d,e,f,c,a[g+1],21,-2054922799),c=n(c,d,e,f,a[g+8],6,1873313359),f=n(f,c,d,e,a[g+15],10,-30611744),e=n(e,f,c,d,a[g+6],15,-1560198380),d=n(d,e,f,c,a[g+13],21,1309151649),c=n(c,d,e,f,a[g+4],6,-145523070),f=n(f,c,d,e,a[g+11],10,-1120210379),e=n(e,f,c,d,a[g+2],15,718787259),d=n(d,e,f,c,a[g+9],21,-343485551),c=p(c,h),d=p(d,i),e=p(e,j),f=p(f,o)}return[c,d,e,f]}function j(a,b,c,d,e,f){return p(q(p(p(b,a),p(d,f)),e),c)}function k(a,b,c,d,e,f,g){return j(b&c|~b&d,a,b,e,f,g)}function l(a,b,c,d,e,f,g){return j(b&d|c&~d,a,b,e,f,g)}function m(a,b,c,d,e,f,g){return j(b^c^d,a,b,e,f,g)}function n(a,b,c,d,e,f,g){return j(c^(b|~d),a,b,e,f,g)}function p(a,b){var c=(a&65535)+(b&65535),d=(a>>16)+(b>>16)+(c>>16);return d<<16|c&65535}function q(a,b){return a<>>32-b}function r(a){for(var b=[],d=(1<e;e+=c)b[e>>5]|=(a.charCodeAt(e/c)&d)<e;e++)d+=c.charAt(b[e>>2]>>e%4*8+4&15)+c.charAt(b[e>>2]>>e%4*8&15);return d}var a=0,c=8;return function(a){return t(i(r(a),a.length*c))}}()); \ No newline at end of file diff --git a/package/lean/luci-app-kuainiao/root/www/luci-static/resources/rsa.js b/package/lean/luci-app-kuainiao/root/www/luci-static/resources/rsa.js new file mode 100644 index 000000000..0e012c300 --- /dev/null +++ b/package/lean/luci-app-kuainiao/root/www/luci-static/resources/rsa.js @@ -0,0 +1 @@ +var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var b64padchar="=";function hex2b64(h){var i;var c;var ret="";for(i=0;i+3<=h.length;i+=3){c=parseInt(h.substring(i,i+3),16);ret+=b64map.charAt(c>>6)+b64map.charAt(c&63)}if(i+1==h.length){c=parseInt(h.substring(i,i+1),16);ret+=b64map.charAt(c<<2)}else{if(i+2==h.length){c=parseInt(h.substring(i,i+2),16);ret+=b64map.charAt(c>>2)+b64map.charAt((c&3)<<4)}}while((ret.length&3)>0){ret+=b64padchar}return ret}function b64tohex(s){var ret="";var i;var k=0;var slop;for(i=0;i>2);slop=v&3;k=1}else{if(k==1){ret+=int2char((slop<<2)|(v>>4));slop=v&15;k=2}else{if(k==2){ret+=int2char(slop);ret+=int2char(v>>2);slop=v&3;k=3}else{ret+=int2char((slop<<2)|(v>>4));ret+=int2char(v&15);k=0}}}}if(k==1){ret+=int2char(slop<<2)}return ret}function b64toBA(s){var h=b64tohex(s);var i;var a=new Array();for(i=0;2*i=0){var v=x*this[i++]+w[j]+c;c=Math.floor(v/67108864);w[j++]=v&67108863}return c}function am2(i,x,w,j,c,n){var xl=x&32767,xh=x>>15;while(--n>=0){var l=this[i]&32767;var h=this[i++]>>15;var m=xh*l+h*xl;l=xl*l+((m&32767)<<15)+w[j]+(c&1073741823);c=(l>>>30)+(m>>>15)+xh*h+(c>>>30);w[j++]=l&1073741823}return c}function am3(i,x,w,j,c,n){var xl=x&16383,xh=x>>14;while(--n>=0){var l=this[i]&16383;var h=this[i++]>>14;var m=xh*l+h*xl;l=xl*l+((m&16383)<<14)+w[j]+c;c=(l>>28)+(m>>14)+xh*h;w[j++]=l&268435455}return c}if(j_lm&&(navigator.appName=="Microsoft Internet Explorer")){BigInteger.prototype.am=am2;dbits=30}else{if(j_lm&&(navigator.appName!="Netscape")){BigInteger.prototype.am=am1;dbits=26}else{BigInteger.prototype.am=am3;dbits=28}}BigInteger.prototype.DB=dbits;BigInteger.prototype.DM=((1<=0;--i){r[i]=this[i]}r.t=this.t;r.s=this.s}function bnpFromInt(x){this.t=1;this.s=(x<0)?-1:0;if(x>0){this[0]=x}else{if(x<-1){this[0]=x+this.DV}else{this.t=0}}}function nbv(i){var r=nbi();r.fromInt(i);return r}function bnpFromString(s,b){var k;if(b==16){k=4}else{if(b==8){k=3}else{if(b==256){k=8}else{if(b==2){k=1}else{if(b==32){k=5}else{if(b==4){k=2}else{this.fromRadix(s,b);return}}}}}}this.t=0;this.s=0;var i=s.length,mi=false,sh=0;while(--i>=0){var x=(k==8)?s[i]&255:intAt(s,i);if(x<0){if(s.charAt(i)=="-"){mi=true}continue}mi=false;if(sh==0){this[this.t++]=x}else{if(sh+k>this.DB){this[this.t-1]|=(x&((1<<(this.DB-sh))-1))<>(this.DB-sh))}else{this[this.t-1]|=x<=this.DB){sh-=this.DB}}if(k==8&&(s[0]&128)!=0){this.s=-1;if(sh>0){this[this.t-1]|=((1<<(this.DB-sh))-1)<0&&this[this.t-1]==c){--this.t}}function bnToString(b){if(this.s<0){return"-"+this.negate().toString(b)}var k;if(b==16){k=4}else{if(b==8){k=3}else{if(b==2){k=1}else{if(b==32){k=5}else{if(b==4){k=2}else{return this.toRadix(b)}}}}}var km=(1<0){if(p>p)>0){m=true;r=int2char(d)}while(i>=0){if(p>(p+=this.DB-k)}else{d=(this[i]>>(p-=k))&km;if(p<=0){p+=this.DB;--i}}if(d>0){m=true}if(m){r+=int2char(d)}}}return m?r:"0"}function bnNegate(){var r=nbi();BigInteger.ZERO.subTo(this,r);return r}function bnAbs(){return(this.s<0)?this.negate():this}function bnCompareTo(a){var r=this.s-a.s;if(r!=0){return r}var i=this.t;r=i-a.t;if(r!=0){return(this.s<0)?-r:r}while(--i>=0){if((r=this[i]-a[i])!=0){return r}}return 0}function nbits(x){var r=1,t;if((t=x>>>16)!=0){x=t;r+=16}if((t=x>>8)!=0){x=t;r+=8}if((t=x>>4)!=0){x=t;r+=4}if((t=x>>2)!=0){x=t;r+=2}if((t=x>>1)!=0){x=t;r+=1}return r}function bnBitLength(){if(this.t<=0){return 0}return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM))}function bnpDLShiftTo(n,r){var i;for(i=this.t-1;i>=0;--i){r[i+n]=this[i]}for(i=n-1;i>=0;--i){r[i]=0}r.t=this.t+n;r.s=this.s}function bnpDRShiftTo(n,r){for(var i=n;i=0;--i){r[i+ds+1]=(this[i]>>cbs)|c;c=(this[i]&bm)<=0;--i){r[i]=0}r[ds]=c;r.t=this.t+ds+1;r.s=this.s;r.clamp()}function bnpRShiftTo(n,r){r.s=this.s;var ds=Math.floor(n/this.DB);if(ds>=this.t){r.t=0;return}var bs=n%this.DB;var cbs=this.DB-bs;var bm=(1<>bs;for(var i=ds+1;i>bs}if(bs>0){r[this.t-ds-1]|=(this.s&bm)<>=this.DB}if(a.t>=this.DB}c+=this.s}else{c+=this.s;while(i>=this.DB}c-=a.s}r.s=(c<0)?-1:0;if(c<-1){r[i++]=this.DV+c}else{if(c>0){r[i++]=c}}r.t=i;r.clamp()}function bnpMultiplyTo(a,r){var x=this.abs(),y=a.abs();var i=x.t;r.t=i+y.t;while(--i>=0){r[i]=0}for(i=0;i=0){r[i]=0}for(i=0;i=x.DV){r[i+x.t]-=x.DV;r[i+x.t+1]=1}}if(r.t>0){r[r.t-1]+=x.am(i,x[i],r,2*i,0,1)}r.s=0;r.clamp()}function bnpDivRemTo(m,q,r){var pm=m.abs();if(pm.t<=0){return}var pt=this.abs();if(pt.t0){pm.lShiftTo(nsh,y);pt.lShiftTo(nsh,r)}else{pm.copyTo(y);pt.copyTo(r)}var ys=y.t;var y0=y[ys-1];if(y0==0){return}var yt=y0*(1<1)?y[ys-2]>>this.F2:0);var d1=this.FV/yt,d2=(1<=0){r[r.t++]=1;r.subTo(t,r)}BigInteger.ONE.dlShiftTo(ys,t);t.subTo(y,y);while(y.t=0){var qd=(r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);if((r[i]+=y.am(0,qd,r,j,0,ys))0){r.rShiftTo(nsh,r)}if(ts<0){BigInteger.ZERO.subTo(r,r)}}function bnMod(a){var r=nbi();this.abs().divRemTo(a,null,r);if(this.s<0&&r.compareTo(BigInteger.ZERO)>0){a.subTo(r,r)}return r}function Classic(m){this.m=m}function cConvert(x){if(x.s<0||x.compareTo(this.m)>=0){return x.mod(this.m)}else{return x}}function cRevert(x){return x}function cReduce(x){x.divRemTo(this.m,null,x)}function cMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}function cSqrTo(x,r){x.squareTo(r);this.reduce(r)}Classic.prototype.convert=cConvert;Classic.prototype.revert=cRevert;Classic.prototype.reduce=cReduce;Classic.prototype.mulTo=cMulTo;Classic.prototype.sqrTo=cSqrTo;function bnpInvDigit(){if(this.t<1){return 0}var x=this[0];if((x&1)==0){return 0}var y=x&3;y=(y*(2-(x&15)*y))&15;y=(y*(2-(x&255)*y))&255;y=(y*(2-(((x&65535)*y)&65535)))&65535;y=(y*(2-x*y%this.DV))%this.DV;return(y>0)?this.DV-y:-y}function Montgomery(m){this.m=m;this.mp=m.invDigit();this.mpl=this.mp&32767;this.mph=this.mp>>15;this.um=(1<<(m.DB-15))-1;this.mt2=2*m.t}function montConvert(x){var r=nbi();x.abs().dlShiftTo(this.m.t,r);r.divRemTo(this.m,null,r);if(x.s<0&&r.compareTo(BigInteger.ZERO)>0){this.m.subTo(r,r)}return r}function montRevert(x){var r=nbi();x.copyTo(r);this.reduce(r);return r}function montReduce(x){while(x.t<=this.mt2){x[x.t++]=0}for(var i=0;i>15)*this.mpl)&this.um)<<15))&x.DM;j=i+this.m.t;x[j]+=this.m.am(0,u0,x,i,0,this.m.t);while(x[j]>=x.DV){x[j]-=x.DV;x[++j]++}}x.clamp();x.drShiftTo(this.m.t,x);if(x.compareTo(this.m)>=0){x.subTo(this.m,x)}}function montSqrTo(x,r){x.squareTo(r);this.reduce(r)}function montMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}Montgomery.prototype.convert=montConvert;Montgomery.prototype.revert=montRevert;Montgomery.prototype.reduce=montReduce;Montgomery.prototype.mulTo=montMulTo;Montgomery.prototype.sqrTo=montSqrTo;function bnpIsEven(){return((this.t>0)?(this[0]&1):this.s)==0}function bnpExp(e,z){if(e>4294967295||e<1){return BigInteger.ONE}var r=nbi(),r2=nbi(),g=z.convert(this),i=nbits(e)-1;g.copyTo(r);while(--i>=0){z.sqrTo(r,r2);if((e&(1<0){z.mulTo(r2,g,r)}else{var t=r;r=r2;r2=t}}return z.revert(r)}function bnModPowInt(e,m){var z;if(e<256||m.isEven()){z=new Classic(m)}else{z=new Montgomery(m)}return this.exp(e,z)}BigInteger.prototype.copyTo=bnpCopyTo;BigInteger.prototype.fromInt=bnpFromInt;BigInteger.prototype.fromString=bnpFromString;BigInteger.prototype.clamp=bnpClamp;BigInteger.prototype.dlShiftTo=bnpDLShiftTo;BigInteger.prototype.drShiftTo=bnpDRShiftTo;BigInteger.prototype.lShiftTo=bnpLShiftTo;BigInteger.prototype.rShiftTo=bnpRShiftTo;BigInteger.prototype.subTo=bnpSubTo;BigInteger.prototype.multiplyTo=bnpMultiplyTo;BigInteger.prototype.squareTo=bnpSquareTo;BigInteger.prototype.divRemTo=bnpDivRemTo;BigInteger.prototype.invDigit=bnpInvDigit;BigInteger.prototype.isEven=bnpIsEven;BigInteger.prototype.exp=bnpExp;BigInteger.prototype.toString=bnToString;BigInteger.prototype.negate=bnNegate;BigInteger.prototype.abs=bnAbs;BigInteger.prototype.compareTo=bnCompareTo;BigInteger.prototype.bitLength=bnBitLength;BigInteger.prototype.mod=bnMod;BigInteger.prototype.modPowInt=bnModPowInt;BigInteger.ZERO=nbv(0);BigInteger.ONE=nbv(1);function Arcfour(){this.i=0;this.j=0;this.S=new Array()}function ARC4init(key){var i,j,t;for(i=0;i<256;++i){this.S[i]=i}j=0;for(i=0;i<256;++i){j=(j+this.S[i]+key[i%key.length])&255;t=this.S[i];this.S[i]=this.S[j];this.S[j]=t}this.i=0;this.j=0}function ARC4next(){var t;this.i=(this.i+1)&255;this.j=(this.j+this.S[this.i])&255;t=this.S[this.i];this.S[this.i]=this.S[this.j];this.S[this.j]=t;return this.S[(t+this.S[this.i])&255]}Arcfour.prototype.init=ARC4init;Arcfour.prototype.next=ARC4next;function prng_newstate(){return new Arcfour()}var rng_psize=256;var rng_state;var rng_pool;var rng_pptr;function rng_seed_int(x){rng_pool[rng_pptr++]^=x&255;rng_pool[rng_pptr++]^=(x>>8)&255;rng_pool[rng_pptr++]^=(x>>16)&255;rng_pool[rng_pptr++]^=(x>>24)&255;if(rng_pptr>=rng_psize){rng_pptr-=rng_psize}}function rng_seed_time(){rng_seed_int(new Date().getTime())}if(rng_pool==null){rng_pool=new Array();rng_pptr=0;var t;if(window.crypto&&window.crypto.getRandomValues){var ua=new Uint8Array(32);window.crypto.getRandomValues(ua);for(t=0;t<32;++t){rng_pool[rng_pptr++]=ua[t]}}if(navigator.appName=="Netscape"&&navigator.appVersion<"5"&&window.crypto){var z=window.crypto.random(32);for(t=0;t>>8;rng_pool[rng_pptr++]=t&255}rng_pptr=0;rng_seed_time()}function rng_get_byte(){if(rng_state==null){rng_seed_time();rng_state=prng_newstate();rng_state.init(rng_pool);for(rng_pptr=0;rng_pptr=0&&n>0){var c=s.charCodeAt(i--);if(c<128){ba[--n]=c}else{if((c>127)&&(c<2048)){ba[--n]=(c&63)|128;ba[--n]=(c>>6)|192}else{ba[--n]=(c&63)|128;ba[--n]=((c>>6)&63)|128;ba[--n]=(c>>12)|224}}}ba[--n]=0;var rng=new SecureRandom();var x=new Array();while(n>2){x[0]=0;while(x[0]==0){rng.nextBytes(x)}ba[--n]=x[0]}ba[--n]=0;ba[--n]=0;return new BigInteger(ba)}function pkcs1pad3(s,n){if(n127)&&(c<2048)){ba[j++]=(c>>6)|192;ba[j++]=(c&63)|128}else{ba[j++]=(c>>12)|224;ba[j++]=((c>>6)&63)|128;ba[j++]=(c&63)|128}}}ba[j++]=0;var rng=new SecureRandom();var x=new Array();while(j0&&E.length>0){this.n=parseBigInt(N,16);this.e=parseInt(E,16)}else{alert("Invalid RSA public key")}}function RSADoPublic(x){return x.modPowInt(this.e,this.n)}function RSAEncrypt(text){var m=pkcs1pad3(text,(this.n.bitLength()+7)>>3);if(m==null){return null}var c=this.doPublic(m);if(c==null){return null}var h=c.toString(16);if((h.length&1)==0){return h}else{return"0"+h}}RSAKey.prototype.doPublic=RSADoPublic;RSAKey.prototype.setPublic=RSASetPublic;RSAKey.prototype.encrypt=RSAEncrypt; \ No newline at end of file diff --git a/package/lean/luci-app-kuainiao/root/www/luci-static/resources/sha1.js b/package/lean/luci-app-kuainiao/root/www/luci-static/resources/sha1.js new file mode 100644 index 000000000..11014f81d --- /dev/null +++ b/package/lean/luci-app-kuainiao/root/www/luci-static/resources/sha1.js @@ -0,0 +1,202 @@ +/* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined + * in FIPS PUB 180-1 + * Version 2.1a Copyright Paul Johnston 2000 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for details. + */ + +/* + * Configurable variables. You may need to tweak these to be compatible with + * the server-side, but the defaults work in most cases. + */ +var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ +var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ +var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ + +/* + * These are the functions you'll usually want to call + * They take string arguments and return either hex or base-64 encoded strings + */ +function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));} +function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));} +function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));} +function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));} +function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));} +function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));} + +/* + * Perform a simple self-test to see if the VM is working + */ +function sha1_vm_test() +{ + return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d"; +} + +/* + * Calculate the SHA-1 of an array of big-endian words, and a bit length + */ +function core_sha1(x, len) +{ + /* append padding */ + x[len >> 5] |= 0x80 << (24 - len % 32); + x[((len + 64 >> 9) << 4) + 15] = len; + + var w = Array(80); + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + var e = -1009589776; + + for(var i = 0; i < x.length; i += 16) + { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + var olde = e; + + for(var j = 0; j < 80; j++) + { + if(j < 16) w[j] = x[i + j]; + else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); + var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), + safe_add(safe_add(e, w[j]), sha1_kt(j))); + e = d; + d = c; + c = rol(b, 30); + b = a; + a = t; + } + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + e = safe_add(e, olde); + } + return Array(a, b, c, d, e); + +} + +/* + * Perform the appropriate triplet combination function for the current + * iteration + */ +function sha1_ft(t, b, c, d) +{ + if(t < 20) return (b & c) | ((~b) & d); + if(t < 40) return b ^ c ^ d; + if(t < 60) return (b & c) | (b & d) | (c & d); + return b ^ c ^ d; +} + +/* + * Determine the appropriate additive constant for the current iteration + */ +function sha1_kt(t) +{ + return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : + (t < 60) ? -1894007588 : -899497514; +} + +/* + * Calculate the HMAC-SHA1 of a key and some data + */ +function core_hmac_sha1(key, data) +{ + var bkey = str2binb(key); + if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz); + + var ipad = Array(16), opad = Array(16); + for(var i = 0; i < 16; i++) + { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + + var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz); + return core_sha1(opad.concat(hash), 512 + 160); +} + +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +function safe_add(x, y) +{ + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} + +/* + * Bitwise rotate a 32-bit number to the left. + */ +function rol(num, cnt) +{ + return (num << cnt) | (num >>> (32 - cnt)); +} + +/* + * Convert an 8-bit or 16-bit string to an array of big-endian words + * In 8-bit function, characters >255 have their hi-byte silently ignored. + */ +function str2binb(str) +{ + var bin = Array(); + var mask = (1 << chrsz) - 1; + for(var i = 0; i < str.length * chrsz; i += chrsz) + bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32); + return bin; +} + +/* + * Convert an array of big-endian words to a string + */ +function binb2str(bin) +{ + var str = ""; + var mask = (1 << chrsz) - 1; + for(var i = 0; i < bin.length * 32; i += chrsz) + str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask); + return str; +} + +/* + * Convert an array of big-endian words to a hex string. + */ +function binb2hex(binarray) +{ + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var str = ""; + for(var i = 0; i < binarray.length * 4; i++) + { + str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) + + hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF); + } + return str; +} + +/* + * Convert an array of big-endian words to a base-64 string + */ +function binb2b64(binarray) +{ + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var str = ""; + for(var i = 0; i < binarray.length * 4; i += 3) + { + var triplet = (((binarray[i >> 2] >> 8 * (3 - i %4)) & 0xFF) << 16) + | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 ) + | ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF); + for(var j = 0; j < 4; j++) + { + if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; + else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); + } + } + return str; +}