硅基流动 key 批量测试程序 + 几个已认证的 key

代码是 C 语言写的(地址),可以批量测试 key 对应的用户名,余额,是否支持国内模型,是否支持国外模型。

核心部分:

#include <curl/curl.h>
#include <jansson.h>

#include <stdbool.h>
#include <stdio.h>
#include <string.h>

enum
{
  TYPE_INFO,
  TYPE_MODELS,
  TYPE_CHAT_BASE,
  TYPE_CHAT_ADVANCED,
};

typedef struct result_t result_t;
typedef struct pack_t pack_t;

struct result_t
{
  bool ok;
  char key[55];
  char name[12];
  char balance[16];

  bool base;
  bool advanced;

  void *share;
};

struct pack_t
{
  int type;
  result_t *res;

  char *data;
  size_t size;
};

static void init (void);
static void cleanup (void);
static void work (const char *path);

static CURLM *multi;
static bool got_models;
static char *chat_base_data;
static char *chat_advanced_data;

int
main (int argc, char **argv)
{
  init ();
  work (argc > 1 ? argv[1] : "./keys");
  cleanup ();
}

static void
init (void)
{
  curl_global_init (CURL_GLOBAL_ALL);
  multi = curl_multi_init ();

  json_t *base
      = json_pack ("{s:s,s:[{s:s,s:s}]}", "model", "Qwen/Qwen2.5-72B-Instruct",
                   "messages", "role", "user", "content", "AI 是什么?");
  json_t *advanced
      = json_pack ("{s:s,s:[{s:s,s:s}]}", "model",
                   "meta-llama/Meta-Llama-3.1-405B-Instruct", "messages",
                   "role", "user", "content", "AI 是什么?");

  chat_base_data = json_dumps (base, 0);
  chat_advanced_data = json_dumps (advanced, 0);

  json_decref (base);
  json_decref (advanced);
}

static void
cleanup (void)
{
  free (chat_advanced_data);
  free (chat_base_data);
  curl_multi_cleanup (&multi);
  curl_global_cleanup ();
}

static size_t
callback (char *data, size_t size, size_t nmemb, void *ptr)
{
  pack_t *pack = ptr;
  size_t total = size * nmemb;

  if (pack->type == TYPE_MODELS && got_models)
    return total;

  size_t oldsize = pack->size;
  size_t newsize = oldsize + total;
  char *newdata = realloc (pack->data, newsize);

  memcpy (newdata + oldsize, data, total);
  pack->size = newsize;
  pack->data = newdata;

  return total;
}

static inline void
test (result_t *res, int type)
{
  static const char *urls[] = {
    [TYPE_INFO] = "https://api.siliconflow.cn/v1/user/info",
    [TYPE_MODELS] = "https://api.siliconflow.cn/v1/models",
    [TYPE_CHAT_BASE... TYPE_CHAT_ADVANCED]
    = "https://api.siliconflow.cn/v1/chat/completions",
  };

  CURL *hnd = curl_easy_init ();
  pack_t *pack = malloc (sizeof (pack_t));

  static char hdr_key[80];
  sprintf (hdr_key, "authorization: Bearer %s", res->key);

  struct curl_slist *hdrs;
  if (!(hdrs = res->share))
    {
      hdrs = curl_slist_append (hdrs, "content-type: application/json");
      hdrs = curl_slist_append (hdrs, "accept: application/json");
      hdrs = curl_slist_append (hdrs, hdr_key);
      res->share = hdrs;
    }

  curl_easy_setopt (hnd, CURLOPT_TIMEOUT, 15);
  curl_easy_setopt (hnd, CURLOPT_PRIVATE, pack);
  curl_easy_setopt (hnd, CURLOPT_WRITEDATA, pack);
  curl_easy_setopt (hnd, CURLOPT_HTTPHEADER, hdrs);
  curl_easy_setopt (hnd, CURLOPT_WRITEFUNCTION, callback);

  const char *method = "GET";
  const char *url = urls[type];

  switch (pack->type = type)
    {
    case TYPE_CHAT_BASE:
      curl_easy_setopt (hnd, CURLOPT_POSTFIELDS, chat_base_data);
      method = "POST";
      break;
    case TYPE_CHAT_ADVANCED:
      curl_easy_setopt (hnd, CURLOPT_POSTFIELDS, chat_advanced_data);
      method = "POST";
      break;
    }

  curl_easy_setopt (hnd, CURLOPT_URL, url);
  curl_easy_setopt (hnd, CURLOPT_CUSTOMREQUEST, method);

  curl_multi_add_handle (multi, hnd);
  pack->data = NULL;
  pack->res = res;
  pack->size = 0;
}

static void
hnd_models (pack_t *pack)
{
  json_t *json = json_loadb (pack->data, pack->size, 0, NULL);

  if (json)
    {
      FILE *models = fopen ("./models", "w");
      json_t *arr = json_object_get (json, "data");

      for (size_t n = json_array_size (arr), i = 0; i < n; i++)
        {
          json_t *id = json_object_get (json_array_get (arr, i), "id");
          fputs (json_string_value (id), models);
          fputc ('\n', models);
        }

      json_decref (json);
      got_models = true;
      fclose (models);
    }
}

static void
hnd_info (pack_t *pack)
{
  result_t *res = pack->res;
  json_t *json = json_loadb (pack->data, pack->size, 0, NULL);

  if (json)
    {
      json_t *obj = json_object_get (json, "data");
      json_t *name = json_object_get (obj, "name");
      json_t *balance = json_object_get (obj, "balance");

      strcpy (res->balance, json_string_value (balance));
      strcpy (res->name, json_string_value (name));
      json_decref (json);
      res->ok = true;
    }
}

static inline void
hnd_chat (pack_t *pack)
{
  switch (pack->type)
    {
    case TYPE_CHAT_BASE:
      pack->res->base = true;
      break;
    case TYPE_CHAT_ADVANCED:
      pack->res->advanced = true;
      break;
    }
}

static void
work (const char *path)
{
  int num = 0;
  result_t *results[1024];
  FILE *file = fopen (path, "r");

  for (char key[64]; fgets (key, sizeof (key), file);)
    {
      if (key[0] == '\n')
        continue;

      size_t len = strlen (key);
      key[len - 1] = '\0';

      result_t *res = malloc (sizeof (result_t));
      memcpy (res->key, key, len + 1);
      res->advanced = false;
      res->share = NULL;
      res->base = false;
      res->ok = false;

      results[num++] = res;
      test (res, TYPE_INFO);
      test (res, TYPE_MODELS);
      test (res, TYPE_CHAT_BASE);
      test (res, TYPE_CHAT_ADVANCED);
    }

  for (int n, c; (curl_multi_perform (multi, &n), n);)
    {
      curl_multi_poll (multi, NULL, 0, 1000, NULL);

      for (struct CURLMsg *m; (m = curl_multi_info_read (multi, &c));)
        if (m->msg == CURLMSG_DONE)
          {
            long code;
            pack_t *pack;
            CURL *hnd = m->easy_handle;

            curl_easy_getinfo (hnd, CURLINFO_PRIVATE, &pack);
            curl_easy_getinfo (hnd, CURLINFO_RESPONSE_CODE, &code);

            if (code != 200)
              goto clean;

            if (pack->type == TYPE_MODELS && !got_models)
              hnd_models (pack);
            else if (pack->type == TYPE_INFO)
              hnd_info (pack);
            else
              hnd_chat (pack);

          clean:
            free (pack->data);
            free (pack);

            curl_multi_remove_handle (multi, hnd);
            curl_easy_cleanup (hnd);
          }
    }

  FILE *result = fopen ("./result", "w");
  fputs ("key, name, balance, base, advanced\n", result);

  for (int i = 0; i < num; i++)
    {
      result_t *res = results[i];
      bool ok = res->ok;

      char *key = res->key;
      char *name = ok ? res->name : "";
      char *balance = ok ? res->balance : "";

      char base = res->base ? 'y' : 'n';
      char advanced = res->advanced ? 'y' : 'n';

      fprintf (result, "%s, %s, %s, %c, %c\n", key, name, balance, base,
               advanced);

      curl_slist_free_all (res->share);
      free (res);
    }
}

只在 Linux 上经过测试:

  1. 编译条件:libjanssonlibcurlGNU MakeGcc
  2. 编译命令:make。

使用方法:

  1. 在程序文件同级目录创建keys文件,在文件中列出要测试的 key,一行一个,可以有空行。
  2. 运行 main 程序,结果会输出到models(可用模型列表)和result(余额,是否实名)文件中。

分享几个之前注册的 key:

key, name, balance, base, advanced
sk-nmgpitgxdqdveyetpnahktbewwgoygikabspewyawkwamwlv, 16756112362, 13.913, y, y
sk-luxolynugmclsrgedjauxtxltqfzmehbxlobxuiusbfefkbh, 16532627373, 13.9465, y, y
sk-btfsbsagfkmnwkuqkodggkruuczzrlcjpzgpgfusrvgbigig, 17041023573, 13.9465, y, y
sk-vxivhgpmirzhlufmufofmusdgffswztppwatngizaqpxlcyz, 17178585343, 13.928, y, y
sk-ceceapjpzofcqsswutcndiwjhaxudhhxqtlfxrqiuvbmemrj, 19271175801, 13.9441, y, y
sk-ymebnkuhvspianpixspacvgbaxnzvomdnqnruodnhrljcmks, 17178581634, 13.9517, y, y
8 个赞

前排 支持 点赞

感谢大佬分享。

借楼,我也分享过,可以看我帖子

1 个赞