网上找了下全是PHP或者JS 的,自己写了个C#的:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
namespace WpfApplication1
{
public class ToutiaoASCP
{
/*
* auther : wgscd
* date: 2018-4-28
*/
//https://www.toutiao.com/c/user/article/?page_type=1&user_id=58865304456&max_behot_time=1520622925&count=20&as=A1554AEA1B13257&cp=5AABC3D275071E1&_signature=wQ7S9xAbm68jAWE21IUZHsEO0u
/*
js CODE:
function getAsCp()
{
$as = ''; $cp = '';
$time = time();
$key = strtoupper(dechex($time));
$md5Key = strtoupper(md5($time));
if (8 !== strlen($key)) {
$as = '479BB4B7254C150';
$cp = '7E0AC8874BB0985';
} else {
$md5KeyAsc5 = substr($md5Key, 0, 5);
$md5KeyDesc5 = substr($md5Key, -5);
$as = ''; $cp = '';
for ($i = 0; $i < 5; $i ++) {
$as .= $md5KeyAsc5[$i] . $key[$i];
$cp .= $key[$i + 3] . $md5KeyDesc5[$i];
}
$as = 'A1' . $as . substr($key, -3);
$cp = substr($key, 0, 3) . $cp . 'E1';
}
return array($as, $cp);
*/
public static string generateASCP()
{
string AS = "";
string CP = "";
string md5KeyAsc5 = "";
string md5KeyDesc5 = "";
long time = Timestamp();
string key = time.ToString("X2").ToUpper();
string md5Key = EncryptWithMD5("" + time).ToUpper();
if (8 != key.Length)
{
AS = "479BB4B7254C150";
CP = "7E0AC8874BB0985";
}
else
{
md5KeyAsc5 = md5Key.Substring(0, 5);
md5KeyDesc5 = md5Key.Substring(md5Key.Length - 5);
AS = "";
CP = "";
for (int i = 0; i < 5; i++)
{
AS += md5KeyAsc5[i].ToString() + key[i].ToString();
CP += key[i + 3].ToString() + md5KeyDesc5[i].ToString();
}
AS = "" + "A1" + AS + key.Substring(key.Length - 3);
CP = key.Substring(0, 3) + CP + "E1";
}
return "as=" + AS + "&cp=" + CP;
}
///
/// 当前时间戳
///
///
static long Timestamp()
{
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 当地时区
long timeStamp = (long)(DateTime.Now - startTime).TotalSeconds; // 相差秒数
System.Console.WriteLine(timeStamp);
return timeStamp;
}
///
/// 时间戳转日期
///
///
///
static DateTime TimestampToDatetime(long time)
{
long unixTimeStamp = 1478162177;
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 当地时区
DateTime dt = startTime.AddSeconds (unixTimeStamp);
System.Console.WriteLine(dt.ToString("yyyy/MM/dd HH:mm:ss:ffff"));
return dt;
}
static string EncryptWithMD5(string source)
{
byte[] sor = Encoding.UTF8.GetBytes(source);
MD5 md5 = MD5.Create();
byte[] result = md5.ComputeHash(sor);
StringBuilder strbul = new StringBuilder(40);
for (int i = 0; i < result.Length; i++)
{
strbul.Append(result[i].ToString("x2"));//加密结果"x2"结果为32位,"x3"结果为48位,"x4"结果为64位
}
return strbul.ToString();
}
}
}
转载个JAVA的:
public class ToutiaoUtil {
/**
* 生成 as 和 cp , 用作 API 的请求参数
*
* function () {
* var t = Math.floor((new Date).getTime() / 1e3), i = t.toString(16).toUpperCase(), e = md5(t).toString().toUpperCase();
* if (8 != i.length)return {as: "479BB4B7254C150", cp: "7E0AC8874BB0985"};
* for (var s = e.slice(0, 5), o = e.slice(-5), n = "", a = 0; 5 > a; a++)n += s[a] + i[a];
* for (var l = "", r = 0; 5 > r; r++)l += i[r + 3] + o[r];
* return {as: "A1" + n + i.slice(-3), cp: i.slice(0, 3) + l + "E1"}
* }
*
*/
public static Map getAsCp() {
int t = (int) (System.currentTimeMillis() / 1000);
String i = Integer.toHexString(t).toUpperCase();
String e = getMD5(t + "").toUpperCase();
String s = e.substring(0, 5);
String o = e.substring(e.length() - 5, e.length());
String n = "";
for (int j = 0; 5 > j; j++) {
n += s.substring(j, j + 1) + i.substring(j, j + 1);
}
String l = "";
for (int r = 0; 5 > r; r++) {
l += i.substring(r + 3, r + 3 + 1) + o.substring(r, r + 1);
}
String as = "A1" + n + i.substring(i.length() - 3, i.length());
String cp = i.substring(0, 3) + l + "E1";
Map map = new HashMap<>();
map.put(Constant.AS, as);
map.put(Constant.CP, cp);
return map;
}
/**
* 对字符串 MD5 加密
*/
public static String getMD5(String str) {
try {
// 生成一个 MD5 加密计算摘要
MessageDigest md = MessageDigest.getInstance("MD5");
// 计算 MD5 函数
md.update(str.getBytes());
// digest() 最后确定返回 MD5 hash 值, 返回值为8为字符串
// 因为 MD5 hash 值是16位的hex值, 实际上就是8位的字符
// BigInteger 函数则将8位的字符串转换成 16 位 hex 值, 用字符串来表示得到字符串形式的 hash 值
return new BigInteger(1, md.digest()).toString(16);
} catch (Exception e) {
ErrorAction.print(e);
}
return "";
}
}
java refer:
package com.meiji.toutiao.api; | |
import com.meiji.toutiao.bean.media.MediaProfileBean; | |
import com.meiji.toutiao.bean.media.MediaWendaBean; | |
import com.meiji.toutiao.bean.media.MultiMediaArticleBean; | |
import io.reactivex.Observable; | |
import okhttp3.ResponseBody; | |
import retrofit2.Call; | |
import retrofit2.http.GET; | |
import retrofit2.http.Query; | |
/** | |
* Created by Meiji on 2017/5/20. | |
*/ | |
public interface IMobileMediaApi { | |
/** | |
* 头条号主页信息 | |
* https://is.snssdk.com/user/profile/homepage/v3/json/?media_id=4377795668&to_html=0&source=article_top_author&refer=all | |
* | |
* @param mediaId 头条号ID | |
*/ | |
@GET("https://is.snssdk.com/user/profile/homepage/v3/json/?to_html=0&source=article_top_author&refer=all&aid=13") | |
Observable<MediaProfileBean> getMediaProfile( | |
@Query("media_id") String mediaId); | |
/** | |
* 获取头条号文章 | |
* https://is.snssdk.com/pgc/ma/?page_type=1&max_behot_time=1495181160&media_id=52445544609&output=json&is_json=1&count=10&from=user_profile_app&version=2&as=479BB4B7254C150&cp=585DB1871ED64E1 | |
* | |
* @param mediaId 头条号ID | |
* @param maxBehotTime 时间轴 | |
*/ | |
@GET("https://is.snssdk.com/pgc/ma/?page_type=1&output=json&is_json=1&count=20&from=user_profile_app&version=2") | |
Observable<MultiMediaArticleBean> getMediaArticle( | |
@Query("media_id") String mediaId, | |
@Query("max_behot_time") String maxBehotTime, | |
@Query("as") String as, | |
@Query("cp") String cp); | |
/** | |
* 获取头条号视频 | |
* https://is.snssdk.com/pgc/ma/?page_type=0&max_behot_time=1495181160&media_id=52445544609&output=json&is_json=1&count=10&from=user_profile_app&version=2&as=479BB4B7254C150&cp=585DB1871ED64E1 | |
* | |
* @param mediaId 头条号ID | |
* @param maxBehotTime 时间轴 | |
*/ | |
@GET("https://is.snssdk.com/pgc/ma/?page_type=0&output=json&is_json=1&count=10&from=user_profile_app&version=2") | |
Observable<MultiMediaArticleBean> getMediaVideo( | |
@Query("media_id") String mediaId, | |
@Query("max_behot_time") String maxBehotTime, | |
@Query("as") String as, | |
@Query("cp") String cp); | |
/** | |
* 获取头条号问答 | |
* https://is.snssdk.com/wenda/profile/wendatab/brow/?other_id=6619635172&format=json&from_channel=media_channel | |
* | |
* @param mediaId 头条号ID | |
*/ | |
@GET("https://is.snssdk.com/wenda/profile/wendatab/brow/?format=json&from_channel=media_channel") | |
Observable<MediaWendaBean> getMediaWenda( | |
@Query("other_id") String mediaId); | |
/** | |
* 获取头条号问答(加载更多) | |
* http://is.snssdk.com/wenda/profile/wendatab/loadmore/?other_id=53294853357&format=json&from_channel=media_channel&cursor=6428177292098273538&count=10&offset=undefined | |
* | |
* @param mediaId 头条号ID | |
* @param cursor 偏移量 | |
*/ | |
@GET("http://is.snssdk.com/wenda/profile/wendatab/loadmore/?format=json&from_channel=media_channel&count=10&offset=undefined") | |
Observable<MediaWendaBean> getMediaWendaLoadMore( | |
@Query("other_id") String mediaId, | |
@Query("cursor") String cursor); | |
/** | |
* 获取头条号动态 | |
* https://is.snssdk.com/dongtai/list/v11/?user_id=6619635172&max_cursor=1494916016999 | |
* | |
* @param mediaId 头条号ID | |
* @param maxCursor 偏移量 | |
*/ | |
@GET("https://is.snssdk.com/dongtai/list/v11/?") | |
Call<ResponseBody> getMediaDongtai( | |
@Query("user_id") String mediaId, | |
@Query("max_cursor") int maxCursor); | |
} |