在网上没有看到有 ASP 版本的代码,也翻译一份放上来,因为图方便,便用 jscript 写
省下许多功夫。
<%@ codepage="65001" %><script runat="server" language="jscript">
/**
* @author 林俊海(ialvin.cn) 广东·普宁·里湖
*/
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g, '');
};
function httpGet(strURL) {
with (Server.CreateObject("MSXML2.XMLHTTP")) {
open("GET", strURL, false);
send(null);
return responseText;
}
}
function encode(str) {
str = (str||"").replace(/[ ']/g, "").toLowerCase();
return escape(str).replace(/%u(..)(..)|%(..)|(.)/g, function($, $1, $2, $3, $4) {
if ($1) return $2 + $1;
if ($3) return $3 + "00";
return ("0"+$4.charCodeAt(0).toString(16)).slice(-2);
});
}
function loadXML(strXML) {
var x = Server.CreateObject("MSXML2.DOMDocument");
x.loadXML(strXML);
return x;
}
function conv(i) {
var r = i % 4294967296;
if (i >= 0 && r > 2147483648)
r = r - 4294967296;
if (i < 0 && r < 2147483648)
r = r + 4294967296;
return r;
}
function mConv(ia, ib) {
var o = (ia>0 && ib>0) ? 1 : (ia<0 && ib<0) ? 1 : -1;
var a = ia.toString(2).replace(/\D/g,'').split("").reverse();
var b = ib.toString(2).replace(/\D/g,'').split("").reverse();
var c = []; c.length = 34; c = c.join("0").split("");
for (var i=0; i<b.length; i++) {
if (b[i]=='1') {
for (var j=0; j<a.length && j+i<33; j++)
c[j+i] = c[j+i]-(-a[j]);
}
}
for (var i=0; i<32; i++) {
c[i+1] += parseInt(c[i]/2);
c[i] = c[i] % 2;
}
c = parseInt(c.slice(0, 32).reverse().join(""), 2)*o;
if (o == 1 && c > 2147483648)
c = c - 4294967296;
if (o == -1 && c < 2147483648)
c = c + 4294967296;
return c;
}
function verifyCode(artist, title, lrcId) {
var song = [];
encodeURIComponent(artist+title).replace(/%(..)|(.)/g, function($, $1, $2) {
if ($1)
song.push(parseInt($1, 16));
else
song.push($2.charCodeAt(0));
});
var intVal2 = 0, intVal3 = 0;
var intVal1 = (lrcId & 0xFF00) >> 8;
if ((lrcId & 0xFF0000) == 0) {
intVal3 = 0xFF & ~intVal1;
} else {
intVal3 = 0xFF & ((lrcId & 0xFF0000) >> 16);
}
intVal3 = intVal3 | ((0xFF & lrcId) << 8);
intVal3 = intVal3 << 8;
intVal3 = intVal3 | (0xFF & intVal1);
intVal3 = intVal3 << 8;
if ((lrcId & 0xFF000000) == 0) {
intVal3 = intVal3 | (0xFF & (~lrcId));
} else {
intVal3 = intVal3 | (0xFF & (lrcId >> 24));
}
var uBound = song.length - 1;
while (uBound >= 0) {
var c = song[uBound];
if (c >= 0x80)
c = c - 0x100;
intVal1 = (c + intVal2) & 0xFFFFFFFF;
intVal2 = (intVal2 << (uBound % 2 + 4)) & 0xFFFFFFFF;
intVal2 = (intVal1 + intVal2) & 0xFFFFFFFF;
uBound -= 1;
}
uBound = 0;
intVal1 = 0;
while (uBound <= song.length - 1) {
var c = song[uBound];
if (c >= 128)
c = c - 256;
var intVal4 = (c + intVal1) & 0xFFFFFFFF;
intVal1 = (intVal1 << (uBound % 2 + 3)) & 0xFFFFFFFF;
intVal1 = (intVal1 + intVal4) & 0xFFFFFFFF;
uBound += 1;
}
var intVal5 = conv(intVal2 ^ intVal3) & 0xFFFFFFFF;
intVal5 = conv(intVal5 + (intVal1 | lrcId)) & 0xFFFFFFFF;
intVal5 = mConv(intVal5 , intVal1 | intVal3);
intVal5 = mConv(intVal5 , intVal2 ^ lrcId);
var longVal6 = intVal5;
if (intVal5 > 2147483648)
intVal5 = (intVal5 - 4294967296) & 0xFFFFFFFF;
return intVal5.toString();
}
function query(artist, title) {
var url = "http://ttlrcct.qianqian.com/dll/lyricsvr.dll?sh?Artist=" + encode(artist) + "&Title=" + encode(title)+"&Flags=0";
// 这里可能有多个匹配的结果,这里只选取第一个
var lrc = loadXML(httpGet(url)).selectSingleNode("/result/lrc");
if (lrc == null)
throw new Error("在服务器上找不到匹配的歌词。");
var lrcId = lrc.getAttribute("id");
artist = lrc.getAttribute("artist");
title = lrc.getAttribute("title");
url = "http://ttlrcct2.qianqian.com/dll/lyricsvr.dll?dl?Id=" + lrcId + "&Code=" + verifyCode(artist, title, lrcId);
return {ar:artist, ti:title, lrc:httpGet(url)};
}
Response.ContentType = "text/html; charset=utf-8";
try {
var artist = (Request.QueryString("artist").Item || '').trim();
var title = (Request.QueryString("title").Item || '').trim();
if (title == '')
throw new Error("请传入音乐名称!");
var result = query(artist, title);
var fileName = result.ar + " - " + result.ti + ".lrc";
Response.ContentType = "text/plain; charset=utf-8";
Response.AddHeader("Content-Disposition", "inline; filename=\"" + encodeURIComponent(fileName) + "\"");
Response.Write(result.lrc);
} catch(e) {
Response.Write("查询错误:" + e.message);
}
</script>
Java 版的可以参考: http://www.iscripts.org/forum.php?mod=viewthread&tid=85
当然,这里建议在每查询获得一个音乐的 LRC 歌词的时候,把歌词内容存入本地文件或者数据库中,
这样再下次查询时,可以先从本地查询,查不到了再从千千静听的歌词服务器查询,这样子平均上很大程度的提高 WEB 应用的的响应速度。
原文链接:http://www.iscripts.org/forum.php?mod=viewthread&tid=86