本文讲述的是凯撒密码的其中一种,内容含有前辈的一些解密方法, 半转载
目标:虾米音乐网
分析一下这首歌,地址是: http://www.xiami.com/song/ 1769397120
歌曲ID为: 1769397120
请求XML地址: http://www.xiami.com/song/playlist/id/1769397120 (此处是歌曲ID) /object_name/default/object_id/0
得出XML内容如下:
<playlist xmlns="http://xspf.org/ns/0/" version="1"> <trackList> <track> <title> <![CDATA[ We The People ]]> </title> <song_id>1769397120</song_id> <album_id>370721</album_id> <album_name> <![CDATA[ Everlasting Truth ]]> </album_name> <object_id>1</object_id> <object_name>default</object_name> <insert_type>1</insert_type> <background>[img]http://img.xiami.net/res/player/bimg/bg-5.jpg[/img]</background> <grade>-1</grade> <artist> <![CDATA[ Re:plus;Pismo ]]> </artist> <location> 8h2fmF17274.u3dadd-%EltFii55%F17mtDa8bb15-lt%l.335123ph%eaea3E%p2ec44E7%23_5%6ee9%5%F.o%%7657%kE53%925E3mxm2229E33e7E55f3E-A5i%FF13__Fy9e5E43%n%.a273%92la%eb6b865u </location> <ms/> <lyric>[url]http://www.xiami.com/song/lyrictxt/id/1769397120</lyric>[/url] <pic> [url]http://img.xiami.net/images/album/img34/71534/3707211328600624_1.jpg[/url] </pic> <length>206</length> <tryhq>0</tryhq> <artist_id>71534</artist_id> <rec_note/> </track> </trackList> <lastSongId/> <type>default</type> <type_id>1</type_id> <clearlist/> <vip>0</vip> <vip_role>0</vip_role> <hqset>0</hqset> </playlist>
歌曲信息在内,然而,下载地址被加密:
<location> 8h2fmF17274.u3dadd-%EltFii55%F17mtDa8bb15-lt%l.335123ph%eaea3E%p2ec44E7%23_5%6ee9%5%F.o%%7657%kE53%925E3mxm2229E33e7E55f3E-A5i%FF13__Fy9e5E43%n%.a273%92la%eb6b865u </location>
加密方法使用的就是凯撒加密,我们如何去解开呢?
这串字符串中,把第一个字符 8 拿出来,然后把剩余的字符串分为四部分,若能整除则每部分都一样长,若不能整除,则后余数个字符串少一个字符,这里拆开后为:
[ h2fmF17274.u3dadd-%EltFii55%F17mtDa8bb15-lt%l.335123ph%eaea3E%p2ec44E7%23_5%6ee9%5%F.o%%7657%kE53%925E3mxm2229E33e7E55f3E-A5i%FF13__Fy9e5E43%n%.a273%92la%eb6b865u ]
一共78个字符 8-78%4 = 2,因此数列为[20,20,19,19].然后从第一个字符串的第一个字符开始拼接,若把这个拆分后的字符串数组看成一个二维的字符数组,拼接方式为 [0][0],[1][0],[2][0],[3][0],[4][0],[0][1],[1][1],[2][1],[3][1][4][1]… 拼完之后就是下载的真实地址,最后把^替换为字符0.
前辈的这段文字说明,只是把播放地址给解码出来了,可是还少了一个auth_key,为什么会少了auth_key呢? 原因是上述的解码方式算法有误。 我个人认为是这样的。
/* 虾米音乐下载地址,凯撒数列加密方式。 解密算法。 BY 老D www.laod.cn XXX.php?id=歌曲ID */ <?php function u($t) { $l = substr($t,0,1); $t = substr($t, 1); $tn = strlen($t); $ln = $tn / $l; $r = $tn % $l; $res = array(); for($i=0;$i<$l;$i++) { if($i<$r) $e = $ln+1; else $e = $ln; $m = substr($t, 0, $e); $res[] = str_split($m); $t = substr($t, $e); } $text = ''; for($i=0;$i<$ln;$i++) { for($j=0;$j<$l;$j++) { if(isset($res[$j][$i])) $text .= $res[$j][$i]; else break; } } return str_replace('^', 0, urldecode($text)); } function ua($t) { $l = substr($t,0,1); $t = substr($t, 1); $tn = strlen($t); $ln = floor($tn/$l); $r = $tn % $l; $tex = str_split($t); $text = ''; for($i=0;$i<=$ln;$i++) { for($j=0;$j<$l;$j++) { $n = $j*$ln+$i; if($j<$r) $n += $j; else $n += $r; if(isset($tex[$n])) $text .= $tex[$n]; else break; } } $preg = array('^', '%'); $replace = array(0, '|'); return str_replace($preg, $replace, urldecode(substr($text, 0, $tn))); } function callback($text) { if(isset($_GET['callback'])) { return $_GET['callback'] . '(' . $text . ')'; } else { return $text; } } if(!isset($_GET['id'])) die('lack of the id parameter'); $xml = simplexml_load_file('http://www.xiami.com/song/playlist/id/'.$_GET['id']); $track = $xml->trackList->track; $song = array('id' => (string) $track->song_id, 'title' => (string) $track->title, 'artist' => (string) $track->artist, 'location' => (string) ua($track->location), 'lyric' => (string) $track->lyric, 'pic' => (string) substr($track->pic,0, -5).'4.jpg' ); echo callback(json_encode($song)); ?>
上面的是PHP版的最新虾米音乐地址 凯撒数列解码源代。 欢迎大家在看完本文后帮忙补充本文的解码错误地方。谢谢!
原创文章,作者:老D,如若转载,请注明出处:https://laod.cn/161.html
评论列表(6条)
lihai厉害!!!!
JAVA版的
public class XiaMi
{
public static void main(String[] args)
{
//http://www.xiami.com/song/1795316173
String url=XiaMi.getById(“1795316173”);
System.out.println(url);
}
public static String getById(String id){
//http://www.xiami.com/song/playlist/id/1795316173
String url=”http://www.xiami.com/song/playlist/id/”+id;
String str=httpGet(url);
JSONObject json=XML.toJSONObject(str);
//String data=json.toString(4);
String data = json.getJSONObject(“playlist”).getJSONObject(“trackList”).getJSONObject(“track”).getString(“location”);
data=uu(data);
return data;
}
private static String uu(String str)
{
//System.out.println(str);
int l=Integer.parseInt(str.substring(0, 1));
str = str.substring(1);
int tn=str.length();
int ln=(int)Math.floor((double)tn / (double)l);
int r=tn % l;
char[] tex=str.toCharArray();
String text=””;
for (int i=0;i <= ln;i++)
{
for (int j=0;j < l;j++)
{
int n = j * ln + i;
if (j < r) n += j;
else n += r;
if (n < tex.length)
{
text += tex[n];
}
else
{
break;
}
}
}
text=text.substring(0,text.lastIndexOf("null")+4);
try
{
text = URLDecoder.decode(text, "utf-8");
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
text = text.replace("^", "0");
// text = text.replace("%", "|");
//System.out.println(text);
return text;
}
private static String httpGet(String path)
{
try
{
URL url = new URL(path.trim());
//打开连接
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
if (200 == urlConnection.getResponseCode())
{
//得到输入流
InputStream is =urlConnection.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while (-1 != (len = is.read(buffer)))
{
baos.write(buffer, 0, len);
baos.flush();
}
return baos.toString("utf-8");
}
}
catch
(IOException e)
{
e.printStackTrace();
}
return null;
}
}
好麻烦 用Chrome直接下载多方便
@风一样的江江丶:chrome现在那个插件只显示资源数,不显示下载啊!
@所谓坚强、不过是在逞强™:必须用插件?
如何知道是使用哪种方法加密的呢?