相思故

文章 评论 浏览 29

相思故 2025-02-20 19:29:09

如果我正确理解您,例如,您可以从您想要的变量中征服系数(我使用 mtcars dataset作为示例):

model = lm(mpg ~ ., data=mtcars)
smy = summary(model)
smy$coefficients[1:5,]
#>                Estimate  Std. Error    t value  Pr(>|t|)
#> (Intercept) 12.30337416 18.71788443  0.6573058 0.5181244
#> cyl         -0.11144048  1.04502336 -0.1066392 0.9160874
#> disp         0.01333524  0.01785750  0.7467585 0.4634887
#> hp          -0.02148212  0.02176858 -0.9868407 0.3349553
#> drat         0.78711097  1.63537307  0.4813036 0.6352779

在2022-07-07创建的 a href =“ https://reprex.tidyverse.org” rel =“ nofollow noreferrer”> reprex软件包 (v2.0.1)

If I understand you correctly, you could for example subset the coefficients from the variables you want like this (I use mtcars dataset as an example):

model = lm(mpg ~ ., data=mtcars)
smy = summary(model)
smy$coefficients[1:5,]
#>                Estimate  Std. Error    t value  Pr(>|t|)
#> (Intercept) 12.30337416 18.71788443  0.6573058 0.5181244
#> cyl         -0.11144048  1.04502336 -0.1066392 0.9160874
#> disp         0.01333524  0.01785750  0.7467585 0.4634887
#> hp          -0.02148212  0.02176858 -0.9868407 0.3349553
#> drat         0.78711097  1.63537307  0.4813036 0.6352779

Created on 2022-07-07 by the reprex package (v2.0.1)

如何减少Markdown中的回归输出

相思故 2025-02-20 12:55:26

我阅读官方typepcript文档我建议以下内容:

function MyComponent<T>(props: {
  options: {
    label: string;
    value: T;
  }[];
}) {
  return <div>MyComponent</div>;
}


type DominantHand = "RIGHT" | "LEFT";

function ParentComponent() {
  return (
    <MyComponent<DominantHand>
      options={[
        { label: "Right Hand", value: "RIGHT" },
        { label: "Left Hand", value: "LEFT" },
      ]}
    />
  );
};

After I have read the official typescript documentation I would suggest the following:

function MyComponent<T>(props: {
  options: {
    label: string;
    value: T;
  }[];
}) {
  return <div>MyComponent</div>;
}


type DominantHand = "RIGHT" | "LEFT";

function ParentComponent() {
  return (
    <MyComponent<DominantHand>
      options={[
        { label: "Right Hand", value: "RIGHT" },
        { label: "Left Hand", value: "LEFT" },
      ]}
    />
  );
};

如何通过React组件Prop中的通用类型传递

相思故 2025-02-20 07:29:00

正如User456所说,我忘记了在班级名称之前放一个点。我的代码有效

as user456 said I forget to put a dot before the class name. My code works

如果密码不匹配,则确认password不会显示错误消息

相思故 2025-02-20 07:04:12

由于 pracma :: perms 用于生成所有排列和检查建筑火车的历史,但这可能是一种笨重/效率低下的方法,但我希望它可以为您提供一些线索

library(pracma)

# check if adjacent strings have overlaps
isOverlapped <- function(a, b) {
  for (k in 1:min(nchar(c(a, b)))) {
    if (substr(a, nchar(a) - k + 1, nchar(a)) == substr(b, 1, k)) {
      return(TRUE)
    }
  }
  FALSE
}

# check if a train can be created
checkTrain <- function(v) {
  for (i in 1:(length(v) - 1)) {
    if (!isOverlapped(v[i], v[i + 1])) {
      return(FALSE)
    }
  }
  TRUE
}

# produce all possible trains (based on first_string) with additional words from second_string
lapply(
  second_string ,
  function(x) {
    lst <- asplit(perms(c(first_string, x)), 1)
    lst[sapply(lst,checkTrain)]
  }
)

,您将获得列表

[[1]]
[[1]][[1]]
[1] "house" "self"  "funny" "nymph"

[[1]][[2]]
[1] "nymph" "house" "self"  "funny"

[[1]][[3]]
[1] "funny" "nymph" "house" "self"

[[1]][[4]]
[1] "self"  "funny" "nymph" "house"


[[2]]
list()

[[3]]
list()

[[4]]
list()

[[5]]
[[5]][[1]]
[1] "self"  "fluff" "funny" "nymph"

其中 house 给出 4 可能的火车和 fluff 给出 1 train,而其他单词在 second_string 无法根据 first_string 构建任何火车。

This might be a bulky/inefficient approach, due to pracma::perms for generating all permutations and checking the vadility of building trains, but I hope it could provide you with some clues

library(pracma)

# check if adjacent strings have overlaps
isOverlapped <- function(a, b) {
  for (k in 1:min(nchar(c(a, b)))) {
    if (substr(a, nchar(a) - k + 1, nchar(a)) == substr(b, 1, k)) {
      return(TRUE)
    }
  }
  FALSE
}

# check if a train can be created
checkTrain <- function(v) {
  for (i in 1:(length(v) - 1)) {
    if (!isOverlapped(v[i], v[i + 1])) {
      return(FALSE)
    }
  }
  TRUE
}

# produce all possible trains (based on first_string) with additional words from second_string
lapply(
  second_string ,
  function(x) {
    lst <- asplit(perms(c(first_string, x)), 1)
    lst[sapply(lst,checkTrain)]
  }
)

and you will obtain a list

[[1]]
[[1]][[1]]
[1] "house" "self"  "funny" "nymph"

[[1]][[2]]
[1] "nymph" "house" "self"  "funny"

[[1]][[3]]
[1] "funny" "nymph" "house" "self"

[[1]][[4]]
[1] "self"  "funny" "nymph" "house"


[[2]]
list()

[[3]]
list()

[[4]]
list()

[[5]]
[[5]][[1]]
[1] "self"  "fluff" "funny" "nymph"

where house gives 4 possible trains and fluff gives 1 train, while other words in second_string cannot contribute to building any trains based on first_string.

在单词中找到重叠的字母

相思故 2025-02-19 11:35:13

我在

必要的更改主要在服务器的program.cs中:

using NetMQ;
using NetMQ.Sockets;
using NLog;

Logger _logger = LogManager.GetCurrentClassLogger();

try
{
    using (var responseSocket = new ResponseSocket())
    {
        responseSocket.Bind("tcp://localhost:5556");
        var poller = new NetMQPoller();
        responseSocket.ReceiveReady += RouterSocketOnReceiveReady;
        poller.Add(responseSocket);
        poller.Run();
    }
}
catch (Exception e)
{
    Console.WriteLine(e);
}

Console.ReadKey();

void RouterSocketOnReceiveReady(object? sender, NetMQSocketEventArgs netMqSocketEventArgs)
{
    NetMQMessage? clientMessage = new();
    bool result = netMqSocketEventArgs.Socket.TryReceiveMultipartMessage(new TimeSpan(0, 0, 0, 5),
        ref clientMessage, 5);

    if (result == false || clientMessage == null)
    {
        Console.WriteLine("Something went wrong?!");
        return;
    }

    var clientMessageString = clientMessage.Single().ToByteArray();

    //_logger.Debug("Message from client received: '{0}'", clientMessageString);
    Console.WriteLine(string.Format("Message from client received: '{0}'", string.Join(", ", clientMessageString)));

    netMqSocketEventArgs
        .Socket
        .SendFrame("I have received your message");
}

这是客户端的program.cs:

using NetMQ;
using NetMQ.Sockets;
using NLog;
using System.Text;

Logger _logger = LogManager.GetCurrentClassLogger();

Console.WriteLine("Client. Please enter message for server. Enter 'QUIT' to turn off server");
Console.ReadKey();

var encoding = Encoding.ASCII;

using var collectorDevice = new CollectorDevice("tcp://localhost:5556", "inproc://broker", 3);

collectorDevice.Start();

var tasks = new List<Task>();
for (int i = 0; i < 100; i++)
{
    Console.WriteLine(i);
    int j = i;
    Task t = Task.Factory.StartNew(() =>
    {
        try
        {
            using (var requestSocket = new RequestSocket("inproc://broker"))
            {
                requestSocket.SendFrame(encoding.GetBytes(string.Format("Request client: {0} id: {1}", j, Task.CurrentId)));
                _logger.Debug(string.Format("Request client: {0} id: {1}", j, Task.CurrentId));
                Console.WriteLine(string.Format("Request client: {0} id: {1}", j, Task.CurrentId));

                string responseMessage = requestSocket.ReceiveFrameString();
                _logger.Debug(string.Format("Response from server: {0} id: {1} message: {2}", j, Task.CurrentId, responseMessage));
                Console.WriteLine(string.Format("Response from server: {0} id: {1} message: {2}", j, Task.CurrentId, responseMessage));
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            _logger.Error(e);
        }
    });
    tasks.Add(t);
}

Task.WaitAll(tasks.ToArray());

和客户端的collectordevice.cs:

using NetMQ;
using NetMQ.Sockets;
using NLog;

public class CollectorDevice : IDisposable
{
    private NetMQPoller _poller;
    private RouterSocket _frontendSocket;
    private DealerSocket _backendSocket;
    private readonly string _backEndAddress;
    private readonly string _frontEndAddress;
    private readonly int _expectedFrameCount;
    private readonly ManualResetEvent _startSemaphore = new(false);
    private readonly Thread _localThread;
    private static Logger _logger = LogManager.GetCurrentClassLogger();

    /// <summary>
    /// Constructor
    /// </summary>
    /// <param name="backEndAddress"></param>
    /// <param name="frontEndAddress"></param>
    /// <param name="expectedFrameCount"></param>
    public CollectorDevice(string backEndAddress, string frontEndAddress, int expectedFrameCount)
    {
        _expectedFrameCount = expectedFrameCount;

        _backEndAddress = backEndAddress;
        _frontEndAddress = frontEndAddress;

        _frontendSocket = new RouterSocket(_frontEndAddress);
        _backendSocket = new DealerSocket(_backEndAddress);

        _backendSocket.ReceiveReady += OnBackEndReady;
        _frontendSocket.ReceiveReady += OnFrontEndReady;

        _poller = new NetMQPoller { _frontendSocket, _backendSocket };

        _localThread = new Thread(DoWork) { Name = "IPC Collector Device Thread" };
    }

    public void Start()
    {
        _localThread.Start();
        _startSemaphore.WaitOne();
    }

    public void Stop()
    {
        _poller.Stop();
    }

    #region Implementation of IDisposable

    public void Dispose()
    {
        Stop();
    }

    #endregion


    #region Private Methods
    private void DoWork()
    {
        try
        {
            _startSemaphore.Set();

            _poller.Run();
        }
        catch (Exception e)
        {
            _logger.Error(e);
        }
    }

    private void OnBackEndReady(object? sender, NetMQSocketEventArgs e)
    {
        NetMQMessage message = _backendSocket.ReceiveMultipartMessage(_expectedFrameCount);
        _frontendSocket.SendMultipartMessage(message);
    }

    private void OnFrontEndReady(object? sender, NetMQSocketEventArgs e)
    {
        NetMQMessage message = _frontendSocket.ReceiveMultipartMessage(_expectedFrameCount);
        _backendSocket.SendMultipartMessage(message);
    }

    #endregion
}

I got my answer at the GitHub issue I opened. The updated code successfully exchanges messages and terminates with 0, but the messages are out of order; additional logic would be required to put the messages in order, but the point of this question was just to exchange messages.

The necessary changes are mostly in the server's Program.cs:

using NetMQ;
using NetMQ.Sockets;
using NLog;

Logger _logger = LogManager.GetCurrentClassLogger();

try
{
    using (var responseSocket = new ResponseSocket())
    {
        responseSocket.Bind("tcp://localhost:5556");
        var poller = new NetMQPoller();
        responseSocket.ReceiveReady += RouterSocketOnReceiveReady;
        poller.Add(responseSocket);
        poller.Run();
    }
}
catch (Exception e)
{
    Console.WriteLine(e);
}

Console.ReadKey();

void RouterSocketOnReceiveReady(object? sender, NetMQSocketEventArgs netMqSocketEventArgs)
{
    NetMQMessage? clientMessage = new();
    bool result = netMqSocketEventArgs.Socket.TryReceiveMultipartMessage(new TimeSpan(0, 0, 0, 5),
        ref clientMessage, 5);

    if (result == false || clientMessage == null)
    {
        Console.WriteLine("Something went wrong?!");
        return;
    }

    var clientMessageString = clientMessage.Single().ToByteArray();

    //_logger.Debug("Message from client received: '{0}'", clientMessageString);
    Console.WriteLine(string.Format("Message from client received: '{0}'", string.Join(", ", clientMessageString)));

    netMqSocketEventArgs
        .Socket
        .SendFrame("I have received your message");
}

Here's the client's Program.cs:

using NetMQ;
using NetMQ.Sockets;
using NLog;
using System.Text;

Logger _logger = LogManager.GetCurrentClassLogger();

Console.WriteLine("Client. Please enter message for server. Enter 'QUIT' to turn off server");
Console.ReadKey();

var encoding = Encoding.ASCII;

using var collectorDevice = new CollectorDevice("tcp://localhost:5556", "inproc://broker", 3);

collectorDevice.Start();

var tasks = new List<Task>();
for (int i = 0; i < 100; i++)
{
    Console.WriteLine(i);
    int j = i;
    Task t = Task.Factory.StartNew(() =>
    {
        try
        {
            using (var requestSocket = new RequestSocket("inproc://broker"))
            {
                requestSocket.SendFrame(encoding.GetBytes(string.Format("Request client: {0} id: {1}", j, Task.CurrentId)));
                _logger.Debug(string.Format("Request client: {0} id: {1}", j, Task.CurrentId));
                Console.WriteLine(string.Format("Request client: {0} id: {1}", j, Task.CurrentId));

                string responseMessage = requestSocket.ReceiveFrameString();
                _logger.Debug(string.Format("Response from server: {0} id: {1} message: {2}", j, Task.CurrentId, responseMessage));
                Console.WriteLine(string.Format("Response from server: {0} id: {1} message: {2}", j, Task.CurrentId, responseMessage));
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            _logger.Error(e);
        }
    });
    tasks.Add(t);
}

Task.WaitAll(tasks.ToArray());

And the client's CollectorDevice.cs:

using NetMQ;
using NetMQ.Sockets;
using NLog;

public class CollectorDevice : IDisposable
{
    private NetMQPoller _poller;
    private RouterSocket _frontendSocket;
    private DealerSocket _backendSocket;
    private readonly string _backEndAddress;
    private readonly string _frontEndAddress;
    private readonly int _expectedFrameCount;
    private readonly ManualResetEvent _startSemaphore = new(false);
    private readonly Thread _localThread;
    private static Logger _logger = LogManager.GetCurrentClassLogger();

    /// <summary>
    /// Constructor
    /// </summary>
    /// <param name="backEndAddress"></param>
    /// <param name="frontEndAddress"></param>
    /// <param name="expectedFrameCount"></param>
    public CollectorDevice(string backEndAddress, string frontEndAddress, int expectedFrameCount)
    {
        _expectedFrameCount = expectedFrameCount;

        _backEndAddress = backEndAddress;
        _frontEndAddress = frontEndAddress;

        _frontendSocket = new RouterSocket(_frontEndAddress);
        _backendSocket = new DealerSocket(_backEndAddress);

        _backendSocket.ReceiveReady += OnBackEndReady;
        _frontendSocket.ReceiveReady += OnFrontEndReady;

        _poller = new NetMQPoller { _frontendSocket, _backendSocket };

        _localThread = new Thread(DoWork) { Name = "IPC Collector Device Thread" };
    }

    public void Start()
    {
        _localThread.Start();
        _startSemaphore.WaitOne();
    }

    public void Stop()
    {
        _poller.Stop();
    }

    #region Implementation of IDisposable

    public void Dispose()
    {
        Stop();
    }

    #endregion


    #region Private Methods
    private void DoWork()
    {
        try
        {
            _startSemaphore.Set();

            _poller.Run();
        }
        catch (Exception e)
        {
            _logger.Error(e);
        }
    }

    private void OnBackEndReady(object? sender, NetMQSocketEventArgs e)
    {
        NetMQMessage message = _backendSocket.ReceiveMultipartMessage(_expectedFrameCount);
        _frontendSocket.SendMultipartMessage(message);
    }

    private void OnFrontEndReady(object? sender, NetMQSocketEventArgs e)
    {
        NetMQMessage message = _frontendSocket.ReceiveMultipartMessage(_expectedFrameCount);
        _backendSocket.SendMultipartMessage(message);
    }

    #endregion
}

NETMQ当前正确的请求响应模式是什么?

相思故 2025-02-19 08:44:21

您有两种选择用于访问B公司(帐户B)中的数据:

  1. 在公司A(帐户A)中添加用户也成为帐户B中的用户(用户可以拥有会员资格多个以上帐户。)
  2. 要访问帐户B(公司B)中的数据,请模仿帐户中的A(不同)用户。这是通过Esign Admin应用程序或ORG Admin应用程序完成的。

根据设计,不在帐户B中的用户无法访问帐户B中的任何数据

。 App的集成密钥(客户端ID) - 生产中的所有客户端ID均可与任何用户一起使用,并可以使用用户访问的任何帐户。

要查看当前用户可以访问的哪个帐户,请使用/oauth/userInfo API方法。

添加

时,当您获得消息时,用户在此帐户中没有有效的会员资格检查:

  1. 请求使用什么帐户? (请求的URL是什么?)
  2. 该请求是否发送到该帐户的右基本URL
  3. 当前访问令牌在调用/oauth/userInfo api方法时提供了什么结果。

您的测试API呼叫应为:

  1. 获取访问令牌
  2. 呼叫 /oauth /userInfo
  3. call eSign API(例如 /oauth /userInfo中列出的每个帐户)

You have two choices for accessing data in Company B (Account B):

  1. Add the user in Company A (Account A) to also be a user in Account B. (Users can have memberships in more than one account.)
  2. To access the data in Account B (Company B), impersonate a (different) user who is in account B. This is done via the eSign Admin app or via the Org Admin app.

By design, a user who is not in Account B cannot access any data in Account B. (This is the error message you're receiving.)

Note: you do not need to make any changes to your app's integration key (client ID)--all client IDs in production can be used with any user, with any account the user has access to.

To see which accounts the current user has access to, use the /oauth/userinfo API method.

Added

When you get the message User does not have a valid membership in this account check:

  1. What account is the request using? (What is the URL of the request?)
  2. Was the request sent to the right base url for the account?
  3. What result does the current access token provide when calling the /oauth/userinfo API method.

Your test API calls should be:

  1. Get an access token
  2. Call /oauth/userinfo
  3. Call the eSign API (eg list envelopes or somesuch) for each of the accounts listed in /oauth/userinfo

同一组织中多个帐户之间的API集成

相思故 2025-02-19 07:58:38

我建议使用node.js连接器,例如支持批处理操作的Mariadb的Node.js。对于MySQL数据库,驱动程序重写/优化了您的插入语句,对于Mariadb数据库,它将使用批量功能,该功能允许仅使用一个往返发送插入/更新/删除。

document MariaDB的node JS批处理还包含批处理和单个执行之间的性能比较。

I would suggest to use a node.js connector like MariaDB's node.js which supports batch operations. For MySQL databases the driver rewrites/optimizes your insert statement, for MariaDB databases it will use the bulk feature which allows to send insert/update/delete with only one roundtrip.

The Documentation for MariaDB's node.js batch also contains a performance comparision between batch and single execution.

批次插入 /更新交易的KNEX查询优化

相思故 2025-02-19 00:03:27

您应该能够在应用程序配置中定义 @bean newtopic 资源,从属性中解析或代码。

分区计数不能动态。您应该知道有多少消费者需要提前进行绝对排序或最大并行性。分区数量只能增加,但是这样做会失去主题的订购

You should be able to define @Bean NewTopic resources in your application configuration, either parsed from properties, or in code.

The partition count cannot be dynamic. You should know how many consumers are necessary ahead of time for absolute ordering or for max parallelism. Partition count can only ever increase, but doing so will lose ordering within the topic

在Kafka经纪本身或通过Spring Cloud流中配置主题

相思故 2025-02-18 18:30:55

Google的客户库全部支持应用程序默认凭证a>非常有帮助,包括自动查找凭据。您应该利用它。

当您的代码在云功能服务上运行时,它将作为服务帐户身份运行。您可能会使用。部署时,您可以指定用户定义的服务帐户|更新云功能。

注意最好使用用户定义的,非默认服务帐户运行云功能。

当云函数试图创建一个云存储客户端时,它会使用其身份(服务帐户)进行操作。

一种解决方案是:

  1. 使用ADC,并使用这些IE storege_client = storege.client()
  2. 调整云函数的服务帐户以具有正确的IAM角色|云存储的权限。

注意您可能应该调整存储桶的IAM策略。因为您在另一个项目中使用了云存储存储桶,所以如果要调整项目的IAM策略,请确保使用Bucket的(!)项目的IAM策略,而不是Cloud Function的项目的IAM策略。

请参阅 cloud Storage的角色>也许角色/storage.ObjectViewer ,因为这包括 storege> storege.objects.list 您需要的许可。

Google's client libraries all support Application Default Credentials (ADCs) very helpfully including finding credentials automatically. You should utilize this.

When your code runs on the Cloud Functions service, it runs as a Service Account identity. You're probably running the Cloud Functions using the default Cloud Functions Service Account. You can specify a user-defined Service Account when you deploy|update the Cloud Function.

NOTE It's better to run your Cloud Functions using user-defined, non-default Service Accounts.

When the Cloud Function tries to create a Cloud Storage client, it does so using it's identity (the Service Account).

A solution is to:

  1. Utilize ADCs and have the Cloud Storage client be created using these i.e. storage_client = storage.Client()
  2. Adjust the Cloud Function's Service Account to have the correct IAM roles|permissions for Cloud Storage.

NOTE You should probably adjust the Bucket's IAM Policy. Because you're using a Cloud Storage Bucket in a different project, if you want to adjust the Project's IAM Policy instead, ensure you use the Bucket's (!) Project's IAM Policy and not the Cloud Function's Project's IAM Policy.

See IAM roles for Cloud Storage: predefined roles and perhaps roles/storage.objectViewer as this includes storage.objects.list permission that you need.

Google云功能使用未找到服务帐户文件

相思故 2025-02-18 08:55:06

解决方案如下:

{
    "/base/*": {
        "target": "http://localhost:8092",
        "secure": false,
        "loglevel": "debug"
    },
    "*": {
        "target": "http://localhost:8081",
        "secure": false,
        "loglevel": "debug"
    }
}

我错过了 port 问题,但该方法还可以。

我得到 504 HTTP错误

订单很重要。
*必须为第二规则。

The solution is as follow:

{
    "/base/*": {
        "target": "http://localhost:8092",
        "secure": false,
        "loglevel": "debug"
    },
    "*": {
        "target": "http://localhost:8081",
        "secure": false,
        "loglevel": "debug"
    }
}

I missmatched port in question but that approach was ok.

I was getting 504 HTTP error.

The order is important.
The * must be second rule.

Angular代理都没有一个

相思故 2025-02-17 17:29:49

实现中唯一的缺陷实际上是整数和字节数组之间的转换。首先,在JavaScript中,最大整数为0x1fffffffffffffff,请参见在这里但是WebCrypto API应用了大型Endian订单。

作为修复程序的第一步,您可以使用 bigint JavaScript的实现和描述了 bigint arraybuffer
之间的转换
由于此实现可用于 arrayBuffer uint8array ,因此需要进行串联的实现,例如,来自
在这里

这稍微改变了您的实现,如下所示(键,IV和密文被导入编码):

(async () => {

// Key import
var keyHex = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
var key = hex2ab(keyHex);
var subtleKey = await window.crypto.subtle.importKey(
    "raw", 
    key,
    { name: "AES-CTR" },
    false, 
    ["encrypt", "decrypt"] 
);

// IV import
var ivHex = "404142434445464748494a4b4c4d4e4f";
var subtleIv = hex2ab(ivHex);

// Ciphertext import
var ciphertextHex = "ef11ad5afa7ad39fe00e0fe7e934dd38c2556dfadcce052cee9d91ee33393b428013d78ed995d5248cadd7be2d855e1adc932167d779923170447505c164eb46b59efd59e695de56512366738072afee57c16a71583346e0eac4a52dbb423b86e1c931ed7bdc3bbc17e5c662ad9cf676a7053ed435eb0968e6b1108531e2f686f491a8e2c02e43edda8162407b9e774f517e8cc8c683bada7044b1573d501a2ac54022ca1e98e26fa0f6ab60485124adb76472af0a5780a0fc2c3332cceed5395339aef3c818996bd24dd5a8d3573eab4646de859b318810dee23fb4558be8932ab790bd87d5f66531943a8bf7c70ea21b44aca6285e1e48a5852fcfa2beda61cd9f0745b8e6c10161678743b307e4ccfcb49e4c44216c32dd7e65a9f408e0aca457a9a92223e14d5d48c7855db0f7cf97e1dd176391beb0c4ecc466c9a6c4cdb211540cfd0448f4cc35b9719f31c9caf440d2aab66a42f92c65993b216449cef809ca65152bd0b509de4a7f859d630e4a5cb5c17eb6815ed1291379fe547801c7ab22501d2da6fd73111697d275b4086b455e66a36e9e8ad62f1910a832e9461606d88c407e6969f2044ff34417d391d0f6c97480264fd3c7e1b45acc";
var ciphertext = hex2ab(ciphertextHex); 

// Decrypt and concat
var length = ciphertext.byteLength;
var chunkSize = 128; // chunkSize in bytes
var index = 0;
var chunks = [];
var aesCounter = bufToBn(subtleIv);
do {
    var newCount = aesCounter + BigInt(index / 16); // index / 16 = number of blocks
    var decrypted = await window.crypto.subtle.decrypt({name: "AES-CTR", counter: bnToBuf(newCount), length: 128}, subtleKey, ciphertext.slice(index, index+chunkSize)); // length in bits
    chunks.push(new Uint8Array(decrypted));
    index += chunkSize;
} while(index < length);
var mergedChunks = merge(chunks);

// Decode and output
var decrypted = String.fromCharCode.apply(null, mergedChunks);
console.log(decrypted);

// https://coolaj86.com/articles/convert-js-bigints-to-typedarrays/
function bnToBuf(bn) {
    var hex = BigInt(bn).toString(16);
    if (hex.length % 2) { hex = '0' + hex; }
    var len = hex.length / 2;
    var u8 = new Uint8Array(len);
    var i = 0;
    var j = 0;
    while (i < len) {
        u8[i] = parseInt(hex.slice(j, j+2), 16);
        i += 1;
        j += 2;
    }
    return u8;
}
function bufToBn(buf) {
    var hex = [];
    u8 = Uint8Array.from(buf);
    u8.forEach(function (i) {
        var h = i.toString(16);
        if (h.length % 2) { h = '0' + h; }
        hex.push(h);
    });
    return BigInt('0x' + hex.join(''));
}

// https://stackoverflow.com/a/49129872/9014097
function merge(chunks){
    let size = 0;
    chunks.forEach(item => {
        size += item.length;
    });
    let mergedArray = new Uint8Array(size);
    let offset = 0;
    chunks.forEach(item => {
        mergedArray.set(item, offset);
        offset += item.length;
    });
    return mergedArray;
}

function hex2ab(hex){
    return new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function (h) {
        return parseInt(h, 16)}));
}

})();

成功地解密了密文。顺便说一句,Ciphertext用 cyberchef


与WebCrypto API不同,Cryptojs支持渐进的加密,因此使用CryptoJs可以更轻松地实现相同的逻辑:

// Key import
var keyHex = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
var keyWA = CryptoJS.enc.Hex.parse(keyHex);

// IV import
var ivHex = "404142434445464748494a4b4c4d4e4f";
var ivWA = CryptoJS.enc.Hex.parse(ivHex);

// Ciphertext import
var ciphertextHex = "ef11ad5afa7ad39fe00e0fe7e934dd38c2556dfadcce052cee9d91ee33393b428013d78ed995d5248cadd7be2d855e1adc932167d779923170447505c164eb46b59efd59e695de56512366738072afee57c16a71583346e0eac4a52dbb423b86e1c931ed7bdc3bbc17e5c662ad9cf676a7053ed435eb0968e6b1108531e2f686f491a8e2c02e43edda8162407b9e774f517e8cc8c683bada7044b1573d501a2ac54022ca1e98e26fa0f6ab60485124adb76472af0a5780a0fc2c3332cceed5395339aef3c818996bd24dd5a8d3573eab4646de859b318810dee23fb4558be8932ab790bd87d5f66531943a8bf7c70ea21b44aca6285e1e48a5852fcfa2beda61cd9f0745b8e6c10161678743b307e4ccfcb49e4c44216c32dd7e65a9f408e0aca457a9a92223e14d5d48c7855db0f7cf97e1dd176391beb0c4ecc466c9a6c4cdb211540cfd0448f4cc35b9719f31c9caf440d2aab66a42f92c65993b216449cef809ca65152bd0b509de4a7f859d630e4a5cb5c17eb6815ed1291379fe547801c7ab22501d2da6fd73111697d275b4086b455e66a36e9e8ad62f1910a832e9461606d88c407e6969f2044ff34417d391d0f6c97480264fd3c7e1b45acc";
var ciphertextWA = CryptoJS.enc.Hex.parse(ciphertextHex);

// Decrypt and concat
var length = ciphertextWA.sigBytes;
var chunkSize = 128;
var index = 0;
var decryptedWA = CryptoJS.enc.Hex.parse("");
var aesDecryptor = CryptoJS.algo.AES.createDecryptor(keyWA, { iv: ivWA, mode: CryptoJS.mode.CTR, padding: CryptoJS.pad.NoPadding });
var chunk = null;
do {   
    chunk = CryptoJS.lib.WordArray.create(ciphertextWA.words.slice(index/4, (index + chunkSize)/4));
    decryptedWA = decryptedWA.concat(aesDecryptor.process(chunk));
    index += chunkSize;
} while(index < length - chunkSize);
chunk = CryptoJS.lib.WordArray.create(ciphertextWA.words.slice(index/4, (index + chunkSize)/4));
chunk.sigBytes = length - index;
chunk.clamp();
decryptedWA = decryptedWA.concat(aesDecryptor.process(chunk));
decryptedWA = decryptedWA.concat(aesDecryptor.finalize());

// Decode and output
var decrypted = decryptedWA.toString(CryptoJS.enc.Utf8);
console.log(decrypted);
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>


第一个变体的缺点是 bigint 类实际上不应在密码学的上下文中使用,因为操作不是恒定的,这会导致易受时间攻击的脆弱性。因此,在这里,您必须在生产上应用一个更安全的JavaScript BigInteger实施。
由于这种原因,使用已建立的库(而不是定制实施),例如Cryptojs,通常更安全(尽管最终在这里也不能排除漏洞)。

The only flaw in your implementation is actually the conversion between integer and byte array. Firstly, in JavaScript the maximum integer is 0x1FFFFFFFFFFFFF, see here, secondly, even with smaller numbers the little endian order is used, but the WebCrypto API applies the big endian order.

As a first step to a fix you could use e.g. the BigInt implementation of JavaScript and the here described conversion between BigInt and ArrayBuffer.
Since this implementation works with ArrayBuffer and Uint8Array respectively, an implementation for concatenation is needed, e.g. from here.

This changes your implementation slightly as follows (key, IV and ciphertext are imported hex encoded):

(async () => {

// Key import
var keyHex = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
var key = hex2ab(keyHex);
var subtleKey = await window.crypto.subtle.importKey(
    "raw", 
    key,
    { name: "AES-CTR" },
    false, 
    ["encrypt", "decrypt"] 
);

// IV import
var ivHex = "404142434445464748494a4b4c4d4e4f";
var subtleIv = hex2ab(ivHex);

// Ciphertext import
var ciphertextHex = "ef11ad5afa7ad39fe00e0fe7e934dd38c2556dfadcce052cee9d91ee33393b428013d78ed995d5248cadd7be2d855e1adc932167d779923170447505c164eb46b59efd59e695de56512366738072afee57c16a71583346e0eac4a52dbb423b86e1c931ed7bdc3bbc17e5c662ad9cf676a7053ed435eb0968e6b1108531e2f686f491a8e2c02e43edda8162407b9e774f517e8cc8c683bada7044b1573d501a2ac54022ca1e98e26fa0f6ab60485124adb76472af0a5780a0fc2c3332cceed5395339aef3c818996bd24dd5a8d3573eab4646de859b318810dee23fb4558be8932ab790bd87d5f66531943a8bf7c70ea21b44aca6285e1e48a5852fcfa2beda61cd9f0745b8e6c10161678743b307e4ccfcb49e4c44216c32dd7e65a9f408e0aca457a9a92223e14d5d48c7855db0f7cf97e1dd176391beb0c4ecc466c9a6c4cdb211540cfd0448f4cc35b9719f31c9caf440d2aab66a42f92c65993b216449cef809ca65152bd0b509de4a7f859d630e4a5cb5c17eb6815ed1291379fe547801c7ab22501d2da6fd73111697d275b4086b455e66a36e9e8ad62f1910a832e9461606d88c407e6969f2044ff34417d391d0f6c97480264fd3c7e1b45acc";
var ciphertext = hex2ab(ciphertextHex); 

// Decrypt and concat
var length = ciphertext.byteLength;
var chunkSize = 128; // chunkSize in bytes
var index = 0;
var chunks = [];
var aesCounter = bufToBn(subtleIv);
do {
    var newCount = aesCounter + BigInt(index / 16); // index / 16 = number of blocks
    var decrypted = await window.crypto.subtle.decrypt({name: "AES-CTR", counter: bnToBuf(newCount), length: 128}, subtleKey, ciphertext.slice(index, index+chunkSize)); // length in bits
    chunks.push(new Uint8Array(decrypted));
    index += chunkSize;
} while(index < length);
var mergedChunks = merge(chunks);

// Decode and output
var decrypted = String.fromCharCode.apply(null, mergedChunks);
console.log(decrypted);

// https://coolaj86.com/articles/convert-js-bigints-to-typedarrays/
function bnToBuf(bn) {
    var hex = BigInt(bn).toString(16);
    if (hex.length % 2) { hex = '0' + hex; }
    var len = hex.length / 2;
    var u8 = new Uint8Array(len);
    var i = 0;
    var j = 0;
    while (i < len) {
        u8[i] = parseInt(hex.slice(j, j+2), 16);
        i += 1;
        j += 2;
    }
    return u8;
}
function bufToBn(buf) {
    var hex = [];
    u8 = Uint8Array.from(buf);
    u8.forEach(function (i) {
        var h = i.toString(16);
        if (h.length % 2) { h = '0' + h; }
        hex.push(h);
    });
    return BigInt('0x' + hex.join(''));
}

// https://stackoverflow.com/a/49129872/9014097
function merge(chunks){
    let size = 0;
    chunks.forEach(item => {
        size += item.length;
    });
    let mergedArray = new Uint8Array(size);
    let offset = 0;
    chunks.forEach(item => {
        mergedArray.set(item, offset);
        offset += item.length;
    });
    return mergedArray;
}

function hex2ab(hex){
    return new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function (h) {
        return parseInt(h, 16)}));
}

})();

which successfully decrypts the ciphertext. Btw, the ciphertext was generated with CyberChef.


Unlike the WebCrypto API, CryptoJS supports progressive encryption, so the same logic can be implemented significantly easier with CryptoJS:

// Key import
var keyHex = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
var keyWA = CryptoJS.enc.Hex.parse(keyHex);

// IV import
var ivHex = "404142434445464748494a4b4c4d4e4f";
var ivWA = CryptoJS.enc.Hex.parse(ivHex);

// Ciphertext import
var ciphertextHex = "ef11ad5afa7ad39fe00e0fe7e934dd38c2556dfadcce052cee9d91ee33393b428013d78ed995d5248cadd7be2d855e1adc932167d779923170447505c164eb46b59efd59e695de56512366738072afee57c16a71583346e0eac4a52dbb423b86e1c931ed7bdc3bbc17e5c662ad9cf676a7053ed435eb0968e6b1108531e2f686f491a8e2c02e43edda8162407b9e774f517e8cc8c683bada7044b1573d501a2ac54022ca1e98e26fa0f6ab60485124adb76472af0a5780a0fc2c3332cceed5395339aef3c818996bd24dd5a8d3573eab4646de859b318810dee23fb4558be8932ab790bd87d5f66531943a8bf7c70ea21b44aca6285e1e48a5852fcfa2beda61cd9f0745b8e6c10161678743b307e4ccfcb49e4c44216c32dd7e65a9f408e0aca457a9a92223e14d5d48c7855db0f7cf97e1dd176391beb0c4ecc466c9a6c4cdb211540cfd0448f4cc35b9719f31c9caf440d2aab66a42f92c65993b216449cef809ca65152bd0b509de4a7f859d630e4a5cb5c17eb6815ed1291379fe547801c7ab22501d2da6fd73111697d275b4086b455e66a36e9e8ad62f1910a832e9461606d88c407e6969f2044ff34417d391d0f6c97480264fd3c7e1b45acc";
var ciphertextWA = CryptoJS.enc.Hex.parse(ciphertextHex);

// Decrypt and concat
var length = ciphertextWA.sigBytes;
var chunkSize = 128;
var index = 0;
var decryptedWA = CryptoJS.enc.Hex.parse("");
var aesDecryptor = CryptoJS.algo.AES.createDecryptor(keyWA, { iv: ivWA, mode: CryptoJS.mode.CTR, padding: CryptoJS.pad.NoPadding });
var chunk = null;
do {   
    chunk = CryptoJS.lib.WordArray.create(ciphertextWA.words.slice(index/4, (index + chunkSize)/4));
    decryptedWA = decryptedWA.concat(aesDecryptor.process(chunk));
    index += chunkSize;
} while(index < length - chunkSize);
chunk = CryptoJS.lib.WordArray.create(ciphertextWA.words.slice(index/4, (index + chunkSize)/4));
chunk.sigBytes = length - index;
chunk.clamp();
decryptedWA = decryptedWA.concat(aesDecryptor.process(chunk));
decryptedWA = decryptedWA.concat(aesDecryptor.finalize());

// Decode and output
var decrypted = decryptedWA.toString(CryptoJS.enc.Utf8);
console.log(decrypted);
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>


A drawback of the first variant is that the BigInt class should actually not be used in the context of cryptography, since the operations are not constant-time, which results in a vulnerability to timing attacks. So, here you would have to apply a cryptographically more secure JavaScript BigInteger implementation for production.
For such reasons, the use of an established library (as opposed to a custom implementation), such as CryptoJS, is generally more secure (although ultimately vulnerabilities cannot be ruled out here either).

如何在JavaScript(浏览器)中使用块AES-CTR块解密大文件(1 GB)?

相思故 2025-02-17 12:14:21

新答案:公共存储桶和CORS现在已经存在,因此您应该能够使用与该页面所述的相同CORS配置规则和方法进行设置。在此处介绍设置公共存储桶和缓存: https .com/r2/data-access/public-buckets/

不通过R2本身来支持ACL,但是您可以使用Cloudflare访问或使用普通的Cloudflare工具来使用Cloudflare访问或其他执行机制(例如, a href =“ https://community.cloudflare.com/t/firewall-rule-to-block-referers-than-than-than-the-sites-domain/72115” rel =“ nofollow noreferrer”> https:https:// https:// 。给定推荐人)。

旧的答案

除非我误读,否则大多数示例页面都是:

  1. 配置公共存储桶,
  2. 配置用于与JS播放器一起使用的COR(对于具有内置支持的浏览器不需要)。
  3. 配置ACL,

我们目前正在实施公共存储桶和COR,这应该启用大部分。在此期间,您可以通过以记录的示例( htttps:/htttps:/htttps:/htttps:/ /developers.cloudflare.com/r2/examples/demo-worker/ )&amp;通过调整响应来添加CORS标头。

我们还将允许您为您的公共存储桶设置虚拟cname,然后
让您可以控制控制推荐人,将访问放在网站前等。

New answer: Public buckets and CORS are now live so you should be able to setup CORS using the same CORS configuration rules and methods as described on that page. Setting up public buckets and caching is described here: https://developers.cloudflare.com/r2/data-access/public-buckets/

ACLs aren't supported via R2 itself but you can use Cloudflare Access or other enforcement mechanisms on the zone that fronts your public bucket using normal Cloudflare tooling (e.g. https://community.cloudflare.com/t/firewall-rule-to-block-referers-other-than-the-sites-domain/72115 for an example on how to setup a firewall rule on your zone to allow list requiring a given referrer).

Old answer

Unless I'm misreading, most of that example page is about:

  1. Configuring a public bucket
  2. Configuring CORS for use with JS players (not needed for browsers with built-in support).
  3. Configuring ACLs

We're currently in the middle of implementing public buckets and CORS which should enable most of this. In the interim, you can make enable it today by taking the documented example (https://developers.cloudflare.com/r2/examples/demo-worker/) & add CORS headers by adjusting the response.

We also will allow you to set a virtual cname to your public bucket which then
lets you control things like controlling referrer, put Access in front of the website, etc.

CloudFlare R2是否能够处理HLS流?

相思故 2025-02-17 12:14:12

看来我发现了如何解决:

WITH RECURSIVE r AS (
    SELECT 'initial'         as t,
           0::numeric(78, 0) as amount,
           0::numeric(78, 0) as event_index,
           0::numeric(78, 0) as total
    UNION ALL
    select all_ordered_events.event_type,
           (
               CASE
                   WHEN event_type = 'added' THEN all_ordered_events.amount
                   WHEN event_type = 'reduce' THEN -all_ordered_events.amount
                   WHEN event_type = 'interest'
                       THEN (r.total / 100 * all_ordered_events.amount)
                   END
               )::numeric(78, 0) as real_amount, -- in case of percent
           all_ordered_events.event_index::numeric(78, 0),
           (
               CASE
                   WHEN event_type = 'added' THEN (r.total + all_ordered_events.amount)
                   WHEN event_type = 'reduce' THEN (r.total - all_ordered_events.amount)
                   WHEN event_type = 'interest'
                       THEN (r.total + (r.total / 100 * all_ordered_events.amount))
                   END
               )::numeric(78, 0) as total
    from all_ordered_events
             JOIN r ON r.event_index + 1 = all_ordered_events.event_index
)
SELECT t, amount, event_index
FROM r

将给我:

t event_index
初始 0 0
添加 100 1
降低 -50 2
兴趣 5 3
添加 500 4
减少 -100 5
利息 91 6

,在我们有类型 ivest /strong>我们看到,在此 event_index 之前,基于从总和计算得出的百分比。

0 + 100-50 + 5(100 -50的10%) + 500-100 + 91(从100-50 + 5 + 500-100 from 20% + 500-100)= 546

现在我可以简单 sum(量)列。

looks like I found how it can be solved:

WITH RECURSIVE r AS (
    SELECT 'initial'         as t,
           0::numeric(78, 0) as amount,
           0::numeric(78, 0) as event_index,
           0::numeric(78, 0) as total
    UNION ALL
    select all_ordered_events.event_type,
           (
               CASE
                   WHEN event_type = 'added' THEN all_ordered_events.amount
                   WHEN event_type = 'reduce' THEN -all_ordered_events.amount
                   WHEN event_type = 'interest'
                       THEN (r.total / 100 * all_ordered_events.amount)
                   END
               )::numeric(78, 0) as real_amount, -- in case of percent
           all_ordered_events.event_index::numeric(78, 0),
           (
               CASE
                   WHEN event_type = 'added' THEN (r.total + all_ordered_events.amount)
                   WHEN event_type = 'reduce' THEN (r.total - all_ordered_events.amount)
                   WHEN event_type = 'interest'
                       THEN (r.total + (r.total / 100 * all_ordered_events.amount))
                   END
               )::numeric(78, 0) as total
    from all_ordered_events
             JOIN r ON r.event_index + 1 = all_ordered_events.event_index
)
SELECT t, amount, event_index
FROM r

Will give me:

t amount event_index
initial 0 0
added 100 1
reduce -50 2
interest 5 3
added 500 4
reduce -100 5
interest 91 6

And where we have type interest we see that the amount now based on percent calculated from total sum before this event_index.

0 + 100 - 50 + 5 (10% from 100 -50) + 500 - 100 + 91 (20% from 100 - 50 + 5 + 500 - 100) = 546

Now I can simple sum(amount) column.

有时以百分比值(基于计算的总和到该行)而不是共同值,有时有时具有百分比值(基于计算的总和)

相思故 2025-02-17 09:20:50

也许您可以向Env注入,然后如您所说的那样发送到您的bash脚本。

  • 示例:
    - name: push change
      env:
        GITHUB_LOGIN: xxx
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        git push https://$GITHUB_LOGIN:[email protected]/$GITHUB_REPOSITORY.git master:master

另外,创建github操作位于位置:

repo-&gt;设置/秘密/操作

maybe you can inject with env and then send to your bash script as you said.

  • example:
    - name: push change
      env:
        GITHUB_LOGIN: xxx
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        git push https://$GITHUB_LOGIN:[email protected]/$GITHUB_REPOSITORY.git master:master

also, create github actions is on the location:

repo -> settings/secrets/actions

如何在github工作流中设置秘密,该秘密被注入不在WorkFlow文件夹中的属性文件中

相思故 2025-02-17 05:34:37

假设您正在使用这个。您可以编辑

helm install airflow -f values airflow-stable/airflow

或直接通过从命令行设置选项:

helm install airflow airflow-stable/airflow --set airflow.image.repository=custom-image-address

对于凭证,有 pullSecret

pullSecret: ""

您可以对此进行编辑,以指定注册表的Docker Secret。
检查此
另外,您可以像上一个示例一样从命令行中设置此选项。

Assuming you are using this one. You can edit the image field in the values and apply it like that:

helm install airflow -f values airflow-stable/airflow

or directly by setting the option from command line:

helm install airflow airflow-stable/airflow --set airflow.image.repository=custom-image-address

For credentials, there is pullSecret

pullSecret: ""

you can edit this to point docker secret for your registry.
Check this.
Also you can set this option from the command line like the previous example.

气流头盔图:如何使用私人注册表中使用自定义Docker图像?

更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

更多

友情链接

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文